给定以下结构 Foo
和处理多种类型的目标(其中 Handle
可以是 Read
、Write
, ETC。)。我知道当我们使用空接口(interface)时我们会丢失编译时类型检查,但除此之外,每种方法的优缺点是什么?最后,实现这一目标最惯用的方法是什么?
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
}
最佳答案
如果您要通过 reflect
处理用户定义的类型,那么空接口(interface)是必需的.那是 fmt.Printf
, json.Encode
, 和 binary.Write
接受它的理由。在Merkle tree scenario方面你之前发布过,你在哈希东西的地方,如果你的Hash()
,你会使用一个空接口(interface)有一个reflect
用于散列用户创建的结构的基于回退。
如果您只打算为几个关键类型( []byte
、 string
等)提供方法,则特定方法可能更有意义。除了编译时检查之外,函数列表还可以作为您可以散列的内容的文档。另一方面,如果有十几种类型您想散列——想想所有 (u)int 类型和它们的 slice ——我想我会使用 interface{}
除非您绝对需要最好的性能,否则只是为了一个整洁的 API,但我认为无论哪种方式都没有明确的共识。
关于performance - 一种功能切换类型与多种类型的功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25578890/