【问题标题】:Golang methods with same name and arity, but different type具有相同名称和数量但类型不同的 Golang 方法
【发布时间】:2021-10-05 23:05:02
【问题描述】:

以下代码可以正常工作。两种方法在两个不同的结构上运行并打印结构的一个字段:

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

为什么我可以在接收器中交换结构类型,但不能在接收器中交换 参数,当方法具有相同的名称和数量?

【问题讨论】:

  • 这不是作者想要做的。

标签: methods struct go


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    您可以使用类型自省。不过,作为一般规则,应避免使用任何泛型 interface{} 类型,除非您正在编写大型泛型框架。

    也就是说,有两种方法可以给众所周知的猫剥皮:

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

    方法一:

    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: p>

        case *A:
            PrintA(v)
        case *B:
            PrintB(v)
    

    工作场示例here

    【讨论】:

      【解决方案3】:

      您不能在 Go 中进行函数或方法重载。在 Go 中你可以有两个同名的方法,但是这些方法的接收者必须是不同的类型。 你可以在this link 看到更多。

      【讨论】:

        猜你喜欢
        • 2013-02-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-07
        • 2020-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多