以下代码正常。两种方法在两个不同的结构上运行并打印结构的一个字段:
type A struct {
Name string
}
type B struct {
Name string
}
func (a *A) Print() {
fmt.Println(a.Name)
}
func (b *B) Print() {
fmt.Println(b.Name)
}
func main() {
a := &A{"A"}
b := &B{"B"}
a.Print()
b.Print()
}
在控制台中显示所需的输出:
A
B
现在,如果我按以下方式更改方法签名,则会出现编译错误。我只是将方法的接收者移动到方法的参数:
func Print(a *A) {
fmt.Println(a.Name)
}
func Print(b *B) {
fmt.Println(b.Name)
}
func main() {
a := &A{"A"}
b := &B{"B"}
Print(a)
Print(b)
}
我甚至无法编译程序:
./test.go:22: Print redeclared in this block
previous declaration at ./test.go:18
./test.go:40: cannot use a (type *A) as type *B in function argument
问题:为什么我可以在接收器中交换结构类型,但不能在 参数,何时方法具有相同的名称和arity?
答案 0 :(得分:33)
因为Go不支持在参数类型上重载用户定义的函数。
您可以使用不同的名称来创建函数,或者如果您只想在一个参数(接收器)上“重载”,则使用方法。
答案 1 :(得分:2)
您可以使用类型内省。但是,作为一般规则,应避免使用通用interface{}
类型,除非您正在编写大型通用框架。
也就是说,有几种方法可以玷污这种众所周知的猫:
两种方法都假设为两种类型(*A
和*B
)定义了Print()方法
方法1:
func Print(any interface{}) {
switch v := any.(type) {
case *A:
v.Print()
case *B:
v.Print()
default:
fmt.Printf("Print() invoked with unsupported type: '%T' (expected *A or *B)\n", any)
return
}
}
方法2:
type Printer interface {
Print()
}
func Print(any interface{}) {
// does the passed value honor the 'Printer' interface
if v, ok := any.(Printer); ok {
// yes - so Print()!
v.Print()
} else {
fmt.Printf("value of type %T passed has no Print() method.\n", any)
return
}
}
如果不希望每种类型都有Print()
方法,请定义定向PrintA(*A)
和PrintB(*B)
函数并更改方法1喜欢这样:
case *A:
PrintA(v)
case *B:
PrintB(v)
工作场所示例here。
答案 2 :(得分:0)
您不能在GOLang中使用不同名称命名函数,但是这些函数的接收者必须具有不同的类型。 您可以在this link中看到更多信息。