【问题标题】:Is it possible to pass interface obj to interface{} type?是否可以将接口 obj 传递给 interface{} 类型?
【发布时间】:2016-11-20 15:29:51
【问题描述】:

我是 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"})
}

所以问题是:

如何确保实现object interface的人会落入case object类型?

提前致谢。

【问题讨论】:

    标签: pointers go types interface go-interface


    【解决方案1】:

    “问题”是someStruct.toByte() 有一个指针接收器。这意味着方法toByte() 属于*someStruct 类型而不是someStruct。所以someStruct 没有实现object,只有*someStruct。你将someStruct 的值传递给overload()

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

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

    输出(在Go Playground 上试试):

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

    规范中的相关部分:Method sets:

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

    幕后

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

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

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

    overload() 内部,type switch 将按列出的顺序检查类型。而当它到达case object时,它会看到包裹在overLoadedObj参数中的值确实实现了object,所以这个case会被执行。

    【讨论】:

    • 太棒了...非常感谢。
    猜你喜欢
    • 2022-06-11
    • 2016-02-12
    • 2020-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-13
    • 2020-11-11
    • 1970-01-01
    相关资源
    最近更新 更多