接口和将匿名字段嵌入到结构中

Dog*_*Dog 0 interface go

当附近发生爆炸时,我正试图代表靠近窗户的人戴眼镜.main是爆炸期间应​​该做什么的草图.有些东西应该收集爆炸附近的物体清单,并为每个物体做特定的事情(例如粉碎或熔化).玻璃和窗户如预期的那样破碎,但出于某种原因,人类也会破碎.为什么?

package main
import "fmt"
type Human struct { Glasses }
type Glasses struct {}
type Shatterable interface { shatter() }
func (g Glasses) shatter() {}
type Window struct {}
func (w Window) shatter() {}

func main() {
    h := Human{Glasses{}}
    objectsInProximity := []interface{}{h,h.Glasses,Window{}}
    for _,o := range objectsInProximity {
        shatter(o)
    }
}

func shatter(i interface{}) {
    s, ok := i.(Shatterable)
    if ok {
        fmt.Printf("shattering a %T\n", s)
        s.shatter()
    }
}
Run Code Online (Sandbox Code Playgroud)

$ go run a.go
shattering a main.Human
shattering a main.Glasses
shattering a main.Window
Run Code Online (Sandbox Code Playgroud)

Von*_*onC 5

正如这个帖子中提到的:

我们谈论的是结构的匿名字段(http://golang.org/ref/spec#Struct_types).

(修改后的版本,因为术语超集令人困惑)

具有匿名字段的结构满足每个接口以及匿名字段或结构本身声明的所有接口方法.

type Human struct { Glasses }
Run Code Online (Sandbox Code Playgroud)

既然Glasses可以破碎,Human也可以满足相同的界面.


注意:在结构中嵌入匿名字段最接近"继承",即使" Golang:当你有多个继承时接口点是什么 "的答案提醒我们:

Go没有继承权.
如果Man'extended' Human(通过将其作为匿名字段),任何用作Human参数的方法都不能Man作为参数.

(这意味着Human延伸...... Glasses?!这可能表现出某种设计缺陷)

我之前在" 如果A嵌入了struct B,可以A访问方法和字段的方法B吗? "中解释说这不是真正的子类型.

接口使函数具有"占位符"参数,该参数可以将不同的结构作为参数.

在这里,如果Human不应该被破坏,它不应该包括匿名字段Glasses.