【问题标题】:Is there a way to generically represent a group of similar functions?有没有办法笼统地表示一组相似的功能?
【发布时间】:2016-12-29 22:27:13
【问题描述】:
package main

import "fmt"

type Pet interface {
    Bark()
}

type Dog int

func (d Dog) Bark() {
    fmt.Println("W! W! W!")
}

type Cat int

func (c Cat) Bark() {
    fmt.Println("M! M! M!")
}

type AdoptFunc func(pet Pet)

func adoptDog(dog Dog) {
    fmt.Println("You live in my house from now on!")
}
func adoptCat(cat Cat) {
    fmt.Println("You live in my house from now on!")
}

func main() {
    var adoptFuncs map[string]AdoptFunc
    adoptFuncs["dog"] = adoptDog // cannot use adoptDog (type func(Dog)) as type AdoptFunc in assignment
    adoptFuncs["cat"] = adoptCat // the same as above
}

如上面的代码,有没有办法用map或者array来收集一堆类似的函数adoptXxx?如果不是,那么在这种情况下使用什么模式是正确的?

【问题讨论】:

  • 使adoptCat 接受Pet 而不是Cat。一般来说:忘记继承和经典的 OOP 并重新设计。恕我直言,宠物、猫和狗是不好的例子。

标签: go interface generic-programming


【解决方案1】:

要将地图用作函数集合,您必须更改函数的签名以匹配。 func(Pet)func(Dog) 的类型不同。

您可以重写AdoptXXX 函数以接收Pet 并进行类型选择以确保输入正确的宠物:

func adoptDog(pet Pet) {
    if _, ok := pet.(Dog); !ok {
        // process incorrect pet type
    }
    fmt.Println("You live in my house from now on!")
}

【讨论】:

  • 从宠物到狗的转换是一件容易的事。例如,如果等效是将字节切片解组为 ProtoBuffer 消息,我还必须在每个类似 OnXxxMessage 的函数中这样做?
  • 解组不完全是类型转换,因为 protobuf 消息只是一个字节序列。 Unmarshal 函数读取此序列并用它填充另一个数据结构。接口用于定义预期的行为。如果一个类型实现了一个接口,那么它就具有该接口的行为。这意味着如果多个具体类型可以表现出相同的行为(尽管它们可能实现不同),您应该使用接口来保存类型,并根据需要调用它们的方法。
  • 在您的具体示例中,OnXxxMessage 函数将接收消息并将其传递给每只监听消息的宠物。这意味着每个OnXxxMessage 都可以直接使用Pet 接口,只要您为接口提供ProcessMessage() 方法之类的东西。
  • 如果每个OnXxxMessage 都需要其特定信息怎么办?
  • 您能否更新您的问题以准确解释您的要求?
猜你喜欢
  • 2022-01-07
  • 2015-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多