【问题标题】:Interfaces and embedding anonymous fields into structs接口和将匿名字段嵌入到结构中
【发布时间】:2014-09-08 17:44:02
【问题描述】:

当附近发生爆炸时,我试图代表一个在窗户附近戴眼镜的人。 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()
    }
}

$ go run a.go
shattering a main.Human
shattering a main.Glasses
shattering a main.Window

【问题讨论】:

  • 如果您不希望 Human 具有 Shatter 方法,请使用 type Human struct { Glasses Glasses }。用机械术语(它们对暴露的 API 执行 X、Y 和 Z)而不是人类语言中的嵌入(以及就此而言,继承)更容易想到。
  • 这个问题让我的一天变得难以置信地亮了????谢谢@dog

标签: interface go


【解决方案1】:

this thread中所述:

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

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

具有匿名字段的结构满足每个接口的所有接口方法,该接口方法由匿名字段或结构本身声明

type Human struct { Glasses }

由于Glasses可以破碎,Human也满足同样的接口。


注意:在结构中嵌入匿名字段最接近“继承”,尽管“Golang: what's the point of interfaces when you have multiple inheritance”的答案提醒我们:

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

(这里的意思是Human 扩展...Glasses?!这可能显示出某种设计缺陷)

我之前在“If struct A is embedded in B, can methods on A access method and fields of B?”中解释过,这不是真正的子类型。

接口使函数能够有一个“占位符”参数,该参数可以将不同的结构作为参数。

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

【讨论】:

  • 不“具有匿名字段的结构满足作为匿名字段方法超集的每个接口”意味着如果A 没有方法,那么struct{A} 将实现每个接口,因为每个接口都是空集的超集?如果B 有一个方法BM,那么struct{B} 将实现每个以BM 作为其方法之一的接口?如果C 有两个方法CM1CM2struct{C} 不会实现interface{CM1,M},因为那不是{CM1,CM2} 的超集?
  • @Dog No:要满足一个接口,你必须实现它的 all 方法。这就是为什么所有结构都满足空接口的原因。
  • 我知道普通接口是这样工作的,但是你粘贴的那个东西暗示(AFAICT)对于匿名字段来说完全不同(与普通接口的工作方式几乎相反)。
  • @Dog superset 可能不是最好的术语,但是接口的所有方法都在 Glasses + Human 中(实际上,这里只在 Glasses 中):答案的重点:匿名字段的方法+主类的方法可以尊重接口。因此人类破碎。
  • @Dog 我试图编辑答案并重新访问引用,但答案的精神仍然存在:如果匿名字段尊重一个接口,通过扩展,嵌入结构也尊重它:Human are Shatterable .
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 2018-01-27
  • 2014-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多