嵌入式结构方法可以了解父/子吗?

我在空闲时间断断续续地使用 Go 工作了几个月,我觉得我已经掌握了它。来自传统的 OOP 语言,如 Java 和 PHP,我很难掌握 Go 中的组合和嵌入。我认为它最近终于被点击并想要更多地使用它,但我的一个想法遇到了障碍。


假设我有一个来自具有 Validate 方法的包的结构,我将它嵌入到我当前正在使用的包中的结构中。 有没有办法(我拥有这两个包)可以获得对结构的引用是在 Validate 方法中嵌入吗?有点像查看谁给我打电话的方式,因为我会在“父”而不是嵌入式上调用它。


我会试着想象这...


type B struct {}

func (b B) Validate() {

  // get reference somehow of A obj

}



type A struct {

  B

}


a := A{B{}}

a.Validate()

我觉得这似乎是不可能的,但如果可以的话会很酷。我想您需要使 A 和 B 都具有相同的接口类型才能使其工作。任何想法或帮助将不胜感激。


墨色风雨
浏览 153回答 2
2回答

交互式爱情

这是不可能的事情。为了更好地理解原因,请查看示例的这个稍微修改过的版本:type B struct{}func (b *B) Validate() {    fmt.Printf("b:%p\n", b)}type A struct {    *B}func main() {    b := B{}    a1 := A{&b}    a2 := A{&b}    a1.Validate()    a2.Validate()    a1.B.Validate()    a2.B.Validate()    b.Validate()}按预期输出,*B到处都是相同的值(Go Playground):b: 0x1becd8b: 0x1becd8b: 0x1becd8b: 0x1becd8b: 0x1becd8如您所见,我将方法接收器和嵌入类型更改为B.从这个例子中可以清楚地看出:您可以使用相同的值B(或者更确切地说是值的相同地址B)来嵌入不同的类型值A!您可以同时调用Validate()两者:因此,对于给定的*B. 这不会破坏交易,但是:如果值为A,您可以B.Validate()通过编写调用提升的方法,a.Validate()这是可以的,但您也可以像这样调用它a.B.Validate()- 现在这一次您实际上没有A(有争议,但Validate()被调用的值为*B和 not A),但最后你也可以调用b.Validate()- 这次你绝对没有A.父级没有明确的类型,B(或*B)可以嵌入任何类型(因此它不能是除 之外的任何类型interface{})。所以形象:你有一个具体的价值,*B当它的Validate()方法被调用时,有时有一个父级,有时没有。那么拥有父母的理由是什么?回到你的例子:为了让这个Validate()方法验证一些有意义的东西,它应该(必须)Validate()作为参数传递给方法 - 显式而不是自动。您能做的最好的事情就是 captncraig 在他的回答(+1) 中所写的内容。如果你显式地添加一个方法,A它会B.Validate()像这样调用,你可以稍微简化一下:func (a *A) Validate2() {    a.Validate(a)}// And using it:a.Validate2()您想象中嵌入的那种验证器没有任何理由A,它应该只是 的一个字段A,或者由于没有直接关系,它可以是一个“独立”的验证器。在这两种情况下Validate(),A如果您想简化验证,您可以添加一个辅助方法。

回首忆惘然

任何类型的parent参考都是不可能的。你希望对父母做什么?由于它们可能是非常不同的类型,因此它们无法做任何有意义的事情。如果您需要不同类型之间的共同点,则需要一个接口,并且需要将其传入:type B struct {}func (b B) Validate(parent MyInterface) {}type A struct {  B}// A implements MyInterfacea := A{B{}}a.Validate(a)如果你能解释你真正想要完成的事情,几乎肯定有比这更好的方法。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go