Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 有没有一种方法可以通用地表示一组类似的函数?_Go_Interface_Generic Programming - Fatal编程技术网

Go 有没有一种方法可以通用地表示一组类似的函数?

Go 有没有一种方法可以通用地表示一组类似的函数?,go,interface,generic-programming,Go,Interface,Generic Programming,正如上面的代码,有没有一种方法可以使用映射或数组来收集一组类似的函数?如果不是,在这种情况下使用什么样的模式是正确的?要将映射用作函数集合,您必须更改函数的签名以匹配func(宠物)与func(狗)的类型不同 您可以重新编写AdoptXXX函数以接收Pet,并进行类型选择以确保输入正确的Pet: package main import "fmt" type Pet interface { Bark() } type Dog int func (d Dog) Bark() {

正如上面的代码,有没有一种方法可以使用映射或数组来收集一组类似的函数?如果不是,在这种情况下使用什么样的模式是正确的?

要将映射用作函数集合,您必须更改函数的签名以匹配
func(宠物)
func(狗)
的类型不同

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

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
}

要将映射用作函数集合,必须更改函数的签名以匹配
func(宠物)
func(狗)
的类型不同

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

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
}

adaptcat
接受
Pet
而不是
Cat
。一般来说:忘记继承和经典的OOP和重新设计吧。宠物、猫和狗都是坏榜样。让
领养猫
接受
宠物
而不是
。一般来说:忘记继承和经典的OOP和重新设计吧。在我看来,宠物、猫和狗都是不好的例子。从宠物变成狗是一件容易的事。例如,如果等价物是将字节片解组到ProtoBuffer消息,那么我还必须在每个类似OnXxxMessage的函数中执行此操作?解组并不完全是类型转换,因为protobuf消息只是一个字节序列。Unmarshal函数读取这个序列并用它填充另一个数据结构。接口用于定义预期的行为。如果一个类型实现了一个接口,那么它具有该接口的行为。因此,这意味着如果多个具体类型可以表现出相同的行为(尽管它们的实现方式可能不同),您应该使用接口来保存这些类型,并根据需要调用它们的方法。在您的特定示例中,
OnXxxMessage
函数将接收消息并将其传递给每个正在侦听消息的宠物。这意味着每个
OnXxxMessage
都可以直接使用
Pet
接口,只要您为该接口提供类似
ProcessMessage()的内容
方法。如果xxxMessage上的每个
都需要它的特定信息怎么办?你能更新你的问题来准确解释你需要什么吗?从宠物到狗的转换是一件容易的事情。例如,如果等价物是将字节片解组到ProtoBuffer消息,那么我还必须在每个类似OnXxxMessage的函数中执行此操作?解组并不完全是类型转换,因为protobuf消息只是一个字节序列。Unmarshal函数读取这个序列并用它填充另一个数据结构。接口用于定义预期的行为。如果一个类型实现了一个接口,那么它具有该接口的行为。因此,这意味着如果多个具体类型可以表现出相同的行为(尽管它们的实现方式可能不同),您应该使用接口来保存这些类型,并根据需要调用它们的方法。在您的特定示例中,
OnXxxMessage
函数将接收消息并将其传递给每个正在侦听消息的宠物。这意味着每个
OnXxxMessage
都可以直接使用
Pet
接口,只要您为该接口提供类似
ProcessMessage()
的方法。如果每个
OnXxxMessage
都需要特定的信息怎么办?您能否更新您的问题以准确解释您需要什么?