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如果您想简化验证,您可以添加一个辅助方法。
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)
如果你能解释你真正想要完成的事情,几乎肯定有比这更好的方法。
- 2 回答
- 0 关注
- 152 浏览
添加回答
举报