为啥直接实现的接口上的这种类型断言会失败?
Posted
技术标签:
【中文标题】为啥直接实现的接口上的这种类型断言会失败?【英文标题】:Why does this Type Assertion on a direct implemented interface fail?为什么直接实现的接口上的这种类型断言会失败? 【发布时间】:2019-03-15 08:26:02 【问题描述】:我正在为 Go 的类型断言机制而苦苦挣扎。在下面的示例中,Qux.(Bar)
的类型断言失败。
为什么在Qux
直接实现DoBar()
不能完全填充Bar
接口?
主包
import (
"fmt"
)
type Nameable interface
Name() string
type Foo interface
Nameable
DoFoo() string
type Bar interface
Nameable
DoBar() string
type bar struct
name string
func (b bar) Name() string
return b.name
// Qux embeds bar and is expected to fullfill Nameable interface
type Qux struct
bar
func (q *Qux) DoBar() string
return "DoBar"
func Check(subject Nameable)
if N, ok := subject.(Nameable); ok
fmt.Printf("%s has Nameable\n", N.Name())
if F, ok := subject.(Foo); ok
fmt.Printf("%s has Foo: %s\n", F.Name(), F.DoFoo())
if B, ok := subject.(Bar); ok
fmt.Printf("%s has Bar: %s\n", B.Name(), B.DoBar())
func main()
Check(barname: "bar")
Check(Quxbar: barname: "Qux")
https://play.golang.org/p/PPkUMUu58JW
输出:
bar has Nameable
Qux has Nameable
【问题讨论】:
只有 *CUx 有 DoBar。停止尝试通过嵌入来模拟继承。嵌入只是语法糖。写出嵌入,你会看到。 @Volker 但是Qux
在类型断言subject.(Bar)
上失败,尽管它实现了DoBar()
本身?!
不,它没有 DoBar 方法。
【参考方案1】:
Qux.DoBar()
有指针接收器,所以只有*Qux
实现了Bar
而不是Qux
。类型Qux
和指向它的指针类型*Qux
是不同的类型,具有不同的method sets。
使用*Qux
类型的值确实实现Bar
:
Check(&Quxbar: barname: "*Qux")
这个输出(在Go Playground上试试):
*Qux has Nameable
*Qux has Bar: DoBar
另外,如果您将Qux.DoBar()
的接收者更改为非指针:
func (q Qux) DoBar() string
return "DoBar"
那么Qux
和*Qux
都会实现Bar
:
Check(barname: "bar")
Check(Quxbar: barname: "Qux")
Check(&Quxbar: barname: "*Qux")
输出(在Go Playground上试试):
bar has Nameable
Qux has Nameable
Qux has Bar: DoBar
*Qux has Nameable
*Qux has Bar: DoBar
查看相关问题:X does not implement Y (... method has a pointer receiver)
【讨论】:
谢谢你,@icza。以上是关于为啥直接实现的接口上的这种类型断言会失败?的主要内容,如果未能解决你的问题,请参考以下文章