Methods 名称和算术相同但类型不同的Golang方法

Methods 名称和算术相同但类型不同的Golang方法,methods,struct,go,Methods,Struct,Go,下面的代码工作正常。在两个不同结构上操作并打印结构字段的两种方法: 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"}

下面的代码工作正常。在两个不同结构上操作并打印结构字段的两种方法:

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时

因为Go不支持在参数类型上重载用户定义函数


您可以使用不同的名称生成函数,或者如果只想在一个参数(接收器)上“重载”,则可以使用方法。

您可以使用类型内省。但是,作为一般规则,应该避免使用泛型
接口{}
类型,除非您正在编写大型泛型框架

也就是说,有几种方法可以剥猫皮:

这两种方法都假定为这两种类型定义了Print()方法(
*a
*B

方法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
    }
}
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
    }
}
方法2:

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
    }
}
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)

工作操场示例。

在GOLang中不能使用不同的名称创建函数,但这些函数的接收器必须是不同类型的。 你可以从中看到更多