一种功能切换类型 vs 多种类型功能

考虑下面的结构Foo和处理多种类型的目标(其中Handle可能Read,Write等等)。我知道当我们使用空接口时,我们会丢失编译时类型检查,但除此之外,每个接口的优缺点是什么?最后,实现这一目标的最惯用的方法是什么?


package main


type Foo struct {

    A int

    B string

}


//Handle all types with switch

func (f *Foo) Handle(obj interface{}) {


    switch obj := obj.(type) {

    case int:

        //do int stuff...

        f.A + obj

    case string:

        //do string stuff...

        f.B + obj

    default:

        panic("Unknown type")

    }

}


//Handle each type individually

func (f *Foo) HandleInt(i int) {

    //do int stuff...

    f.A + i

}

func (f *Foo) HandleString(s string) {

    //do string stuff...

    f.B + s

}


德玛西亚99
浏览 210回答 2
2回答

繁星淼淼

如果您要通过reflect. 那是fmt.Printf,json.Encode和binary.Write的理由接受它。就您之前发布的Merkle 树场景而言,您正在对事物进行哈希处理,如果您Hash()有reflect基于 -based 的回退来对用户创建的结构进行哈希处理,那么您将使用空接口。如果您只打算为几个关键类型([]byte, string, 等等)提供方法,则特定方法可能更有意义。除了编译时检查之外,函数列表还可以作为可以散列的内容的文档。另一方面,如果有,比如,你想要散列的十几种类型——想想所有的 (u)int 类型和它们的切片——我想我会interface{}为了一个整洁而使用API 除非您绝对需要最好的性能,但我认为没有一种明确的共识。

紫衣仙女

一个很好的例子是包排序(来源here),它:确实为基本类型实现了一种方法(如您的第二种方法)建议要排序的类型必须实现的接口。可以对切片和用户定义的集合进行排序如果您对Handle(obj interface{})=>执行相同的操作Handle(obj Interface),这将帮助您使用“ Interface”中声明的方法定义一次处理程序(对于更复杂的类型)。任何满足 say 的类型Interface都会被传递给泛型Handle()函数。你也可以处理切片(类似于这个例子sort)或使用定义的集合。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go