一个函数切换类型与许多类型函数

时间:2014-08-30 04:01:18

标签: performance types go

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

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
}

2 个答案:

答案 0 :(得分:2)

如果您要通过reflect处理用户定义的类型,则必须使用空接口。那是fmt.Printfjson.Encodebinary.Write接受它的理由。就您之前发布的Merkle tree scenario而言,如果您的Hash()基于reflect的回退,您可以使用空白界面。哈希用户创建的结构。

如果您只为几种关键类型([]bytestring提供方法,那么具体方法可能更有意义。除了编译时检查之外,函数列表还可以作为您可以散列的内容的文档。另一方面,如果你想要散列的十多种类型 - 想想所有(u)int类型和它们的切片 - 我想我会使用interface{}只是为了一个整洁的API,除非你绝对需要最好的表现,但我不认为这样或那样明确的共识。

答案 1 :(得分:1)

一个很好的例子是package sortsources here),其中:

  • 确实为基本类型实现了一种方法(如第二种方法)
  • 提出要排序的类型必须实现的interface
  • 可以对切片和用户定义的集合进行排序

如果您对Handle(obj interface{}) =>执行相同的操作Handle(obj Interface),这将帮助您使用“Interface”中声明的方法定义一次(对于更复杂的类型)。 满足所述Interface的任何类型都将传递给通用Handle()函数 你也可以处理切片(类似于this example for sort)或使用定义的集合。