这是不可能的。为了更好地理解原因,请查看您的示例的略微修改版本:
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,您可以通过编写a.Validate() 来调用提升的方法B.Validate(),这没关系,但您也可以像a.B.Validate() 一样调用它 - 现在这一次您真的没有A 的值(有争议,但 Validate() 是在 *B 而不是 A 的值上调用的),但最后你也可以调用 b.Validate() - 这次你肯定没有 @ 的值987654341@.
没有明确的父类型,B(或*B)可以嵌入任何类型(所以它不能是interface{}以外的任何类型)。
所以图像:你有一个具体的值*B,当它的Validate() 方法被调用时,有时有一个父级,有时没有。那么有父母的理由是什么?
回到你的例子:为了让这个 Validate() 方法验证有意义的东西,它应该(必须)作为参数传递给 Validate() 方法 - 显式而不是自动传递。
你能做的最好的就是 captncraig 在his answer (+1) 中写的。
如果你明确地向A 添加一个方法,它会像这样调用B.Validate(),你可以稍微简化一下:
func (a *A) Validate2() {
a.Validate(a)
}
// And using it:
a.Validate2()
没有理由将您想象的那种验证器嵌入A,它应该只是A 的一个字段,或者由于没有直接关系,它可以是一个“独立”的验证器.在这两种情况下,如果您想简化验证,您可以向 A 添加一个帮助器 Validate() 方法。