1

我是 golang 新手,我想实现一个类似于 C++ 重载的重载方法,我的代码如下所示:

type someStruct struct {
    val  int
    some string
}

type object interface {
    toByte()
}

// someStruct implementing an object interface
func (s *someStruct) toByte() {
}

func overload(overLoadedObj interface{}) {

    switch str := overLoadedObj .(type) {
    case string:
        fmt.Println("string : ", str)
    case int:
        fmt.Println("int : ", str)
    case object: //* It doesn't come here at all*
        fmt.Println("interface obj", str)
    }
}

func main() {
    overload("hello")
    overload(5)
    overload(someStruct{val: 5, some: "say"})
}

所以问题是:

如何确保实现对象接口的人将属于案例对象类型?

提前致谢。

4

1 回答 1

2

“问题”是someStruct.toByte()有一个指针接收器。这意味着该方法toByte()属于 type*someStruct而不是someStruct. 所以someStruct不执行object,只有*someStruct。你传递一个someStructto的值overload()

传递 的值*someStruct,你会得到你想要的:

overload(&someStruct{val: 5, some: "say"})

输出(在Go Playground上试试):

string :  hello
int :  5
interface obj &{5 say}

规范中的相关部分:方法集

一个类型可能有一个与之关联的方法集。接口类型的方法集就是它的接口。任何其他类型的方法集由声明为接收者类型T的所有方法T组成。对应指针类型 *T的方法集是所有用receiver *Tor声明的方法的T集合(即它还包含 的方法集T)。

在幕后

请注意,当您这样调用时,在幕后overload()

overload(&someStruct{val: 5, some: "say"})

这会将*someStruct指针值包装在一个interface{}值中(因为overload()有一个interface{}类型的参数),而不是一个类型的接口值object

在里面overload()类型开关将按照列出的顺序检查类型。当它到达时case object,它会看到参数中包装的值overLoadedObj确实实现了object,所以这个案例将被执行。

于 2016-07-18T06:29:02.223 回答