为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
墨色风雨 2021-10-11 10:56:42
我在空闲时间断断续续地使用 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 都具有相同的接口类型才能使其工作。任何想法或帮助将不胜感激。
查看完整描述

2 回答

?
交互式爱情

TA贡献1712条经验 获得超3个赞

这是不可能的事情。为了更好地理解原因,请查看示例的这个稍微修改过的版本:


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: 0x1becd8

b: 0x1becd8

b: 0x1becd8

b: 0x1becd8

b: 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如果您想简化验证,您可以添加一个辅助方法。


查看完整回答
反对 回复 2021-10-11
?
回首忆惘然

TA贡献1847条经验 获得超11个赞

任何类型的parent参考都是不可能的。你希望对父母做什么?由于它们可能是非常不同的类型,因此它们无法做任何有意义的事情。


如果您需要不同类型之间的共同点,则需要一个接口,并且需要将其传入:


type B struct {}

func (b B) Validate(parent MyInterface) {

}



type A struct {

  B

}

// A implements MyInterface

a := A{B{}}

a.Validate(a)

如果你能解释你真正想要完成的事情,几乎肯定有比这更好的方法。


查看完整回答
反对 回复 2021-10-11
  • 2 回答
  • 0 关注
  • 152 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信