为什么直接实现的接口上的这种类型断言会失败?
Why does this Type Assertion on a direct implemented interface fail?
我正在与 Go 的类型断言机制作斗争。在下面的示例中,Qux.(Bar)
的类型断言失败。
为什么 DoBar()
在 Qux
的直接实现没有填满 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(bar{name: "bar"})
Check(Qux{bar: bar{name: "Qux"}})
}
https://play.golang.org/p/PPkUMUu58JW
输出:
bar has Nameable
Qux has Nameable
Qux.DoBar()
有指针接收器,所以只有 *Qux
实现了 Bar
而不是 Qux
。类型 Qux
和指向它的指针类型 *Qux
是具有不同 method sets.
的不同类型
使用 *Qux
类型的值会实现 Bar
:
Check(&Qux{bar: bar{name: "*Qux"}})
此输出(在 Go Playground 上尝试):
*Qux has Nameable
*Qux has Bar: DoBar
此外,如果您将 Qux.DoBar()
的接收器更改为非指针:
func (q Qux) DoBar() string {
return "DoBar"
}
那么Qux
和*Qux
都会实现Bar
:
Check(bar{name: "bar"})
Check(Qux{bar: bar{name: "Qux"}})
Check(&Qux{bar: bar{name: "*Qux"}})
输出(在 Go Playground 上尝试):
bar has Nameable
Qux has Nameable
Qux has Bar: DoBar
*Qux has Nameable
*Qux has Bar: DoBar
参见相关问题:
我正在与 Go 的类型断言机制作斗争。在下面的示例中,Qux.(Bar)
的类型断言失败。
为什么 DoBar()
在 Qux
的直接实现没有填满 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(bar{name: "bar"})
Check(Qux{bar: bar{name: "Qux"}})
}
https://play.golang.org/p/PPkUMUu58JW
输出:
bar has Nameable
Qux has Nameable
Qux.DoBar()
有指针接收器,所以只有 *Qux
实现了 Bar
而不是 Qux
。类型 Qux
和指向它的指针类型 *Qux
是具有不同 method sets.
使用 *Qux
类型的值会实现 Bar
:
Check(&Qux{bar: bar{name: "*Qux"}})
此输出(在 Go Playground 上尝试):
*Qux has Nameable
*Qux has Bar: DoBar
此外,如果您将 Qux.DoBar()
的接收器更改为非指针:
func (q Qux) DoBar() string {
return "DoBar"
}
那么Qux
和*Qux
都会实现Bar
:
Check(bar{name: "bar"})
Check(Qux{bar: bar{name: "Qux"}})
Check(&Qux{bar: bar{name: "*Qux"}})
输出(在 Go Playground 上尝试):
bar has Nameable
Qux has Nameable
Qux has Bar: DoBar
*Qux has Nameable
*Qux has Bar: DoBar
参见相关问题: