Struct 嵌入式结构方法是否可以了解父/子结构?
几个月来,我一直在空闲时间断断续续地和Go一起工作,我觉得我已经掌握了其中的窍门。来自传统的OOP语言,如Java和PHP,我很难掌握Go的组成和嵌入。我想它最近终于点击了,我想更多地使用它,但我有一个想法遇到了障碍 假设我有一个来自一个包的结构,该包有一个Validate方法,我将它嵌入到我当前工作的包的结构中。是否有一种方法(我拥有这两个包)可以获得对正在验证方法内部进行嵌入的结构的引用?有点像是一种看谁给我打电话的方式,因为我会在“家长”而不是嵌入式系统上打电话 我会尝试想象这个Struct 嵌入式结构方法是否可以了解父/子结构?,struct,go,embedding,Struct,Go,Embedding,几个月来,我一直在空闲时间断断续续地和Go一起工作,我觉得我已经掌握了其中的窍门。来自传统的OOP语言,如Java和PHP,我很难掌握Go的组成和嵌入。我想它最近终于点击了,我想更多地使用它,但我有一个想法遇到了障碍 假设我有一个来自一个包的结构,该包有一个Validate方法,我将它嵌入到我当前工作的包的结构中。是否有一种方法(我拥有这两个包)可以获得对正在验证方法内部进行嵌入的结构的引用?有点像是一种看谁给我打电话的方式,因为我会在“家长”而不是嵌入式系统上打电话 我会尝试想象这个 type
type B struct {}
func (b B) Validate() {
// get reference somehow of A obj
}
type A struct {
B
}
a := A{B{}}
a.Validate()
我觉得这似乎是不可能的,但如果你可以的话,那就太酷了。我想您需要使A和B都具有相同的接口类型才能工作。任何想法或帮助都将不胜感激。任何形式的
家长
参考都是不可能的。你希望对父母做什么?因为它们可能是非常不同的类型,所以它们不兼容,无法做任何有意义的事情
如果您需要不同类型之间的共同点,您需要一个接口,并且需要传入:
type B struct {}
func (b B) Validate(parent MyInterface) {
}
type A struct {
B
}
// A implements MyInterface
a := A{B{}}
a.Validate(a)
如果你能解释一下你真正想要实现的目标,那么几乎可以肯定有比这更好的方法 这是不可能的。为了更好地理解原因,请参阅您的示例的这个稍加修改的版本:
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
的值无处不在():
如您所见,我将方法接收器和嵌入类型更改为指针B
从这个例子中可以清楚地看到:您可以使用相同的B
(或者更确切地说是相同的B
)值地址来嵌入不同类型的a
并且您可以对这两种方法调用Validate()
:因此,对于给定的*B
值,理论上的“父级”甚至不是“常量”,这不会破坏交易,但是:如果值为a
,您可以通过编写a.Validate()
调用提升的方法B.Validate()
,这是可以的,但是你也可以像调用a.B.Validate()
-现在你没有真正的a
(有争议,但是Validate()
调用的是*B
而不是a
),但是最后你也可以调用B.Validate()
-这次您肯定没有a
的值
父级没有明确的类型,B
(或*B
)可以嵌入到任何类型中(因此它只能是接口{}
)
如图所示:您有一个具体的值*B
,当调用它的Validate()
方法时,有时有父对象,有时没有父对象。那么,有父母的理由是什么呢
回到您的示例:对于此Validate()
方法来验证有意义的内容,它应该(必须)作为参数显式地而不是自动地传递给Validate()
方法
你所能做的就是captncraig在(+1)中所写的内容
但是,如果显式地向a
添加一个方法,该方法将调用B.Validate()
,如下所示:
func (a *A) Validate2() {
a.Validate(a)
}
// And using it:
a.Validate2()
对于您想象嵌入
a
中的那种验证器没有任何理由,它应该只是a
的一个字段,或者由于没有直接关系,它可以是一个“独立”验证器。在这两种情况下,如果希望简化验证,您可以向a
添加一个helperValidate()
方法。目前,我有一个类似于Java中HIbernate验证的验证库。到目前为止,我有一个您使用的验证方法,如您所建议的:mypackage.validate(myStructOb)。如果有一种方法可以在我想要验证的结构上嵌入一个validate方法并调用它,我会认为它会更干净。我在Java API索引中找不到关于Hibernate的任何信息,所以我不知道你想做什么。我要重申这一答复的第一段。验证
需要了解嵌入它的结构的哪些功能?
func (a *A) Validate2() {
a.Validate(a)
}
// And using it:
a.Validate2()