Inheritance 嵌套结构-get";“基础”;结构
(作为后续问题:) 现在,我可以使用易于编写的文本初始化结构,我稍后在代码中需要访问父结构的成员,但不知道具体的派生类型。是这样的:Inheritance 嵌套结构-get";“基础”;结构,inheritance,struct,go,nested,Inheritance,Struct,Go,Nested,(作为后续问题:) 现在,我可以使用易于编写的文本初始化结构,我稍后在代码中需要访问父结构的成员,但不知道具体的派生类型。是这样的: type A struct { MemberA string } type B struct { A MemberB string } b := B { A: A { MemberA: "test1" }, MemberB: "test2", } fmt.Printf("%+v\n", b) var i interfa
type A struct {
MemberA string
}
type B struct {
A
MemberB string
}
b := B {
A: A { MemberA: "test1" },
MemberB: "test2",
}
fmt.Printf("%+v\n", b)
var i interface{} = b
// later in the code, I only know that I have something that has a nested A,
// I don't know about B (because A is in a library and B is in the
// calling code that uses the library).
// so I want to say "give me the A out of i", so I try a type assertion
if a, ok := i.(A); ok {
fmt.Printf("Yup, A is A: %+v\n", a)
} else {
fmt.Printf("Aristotle (and John Galt) be damned! A is NOT A\n")
}
// no go
然后我就这样使用它:
type A struct {
MemberA string
}
type B struct {
A
MemberB string
}
b := B {
A: A { MemberA: "test1" },
MemberB: "test2",
}
fmt.Printf("%+v\n", b)
var i interface{} = b
// later in the code, I only know that I have something that has a nested A,
// I don't know about B (because A is in a library and B is in the
// calling code that uses the library).
// so I want to say "give me the A out of i", so I try a type assertion
if a, ok := i.(A); ok {
fmt.Printf("Yup, A is A: %+v\n", a)
} else {
fmt.Printf("Aristotle (and John Galt) be damned! A is NOT A\n")
}
// no go
我看到的选择是:
- 我可以使用反射来查找名为“a”的成员,并假设它是正确的类型,使用它。这将是可行的,但效率较低,当然更“笨重”
- 我可以要求调用方实现一个接口(比如
或类似的接口,它返回一个A的实例。到目前为止,这是我能想到的最好的主意HasA{Aval()A}
- 另一点是,我可以让调用者传递一个a值(即在上面的例子中,
变成vari接口{}=b
)。但是实际上,我动态地迭代了b的成员,并对它们进行处理,所以我需要更多的“派生”类型来实现这一点。(我在问题中省略了这一点,因为这只是我为什么会遇到这个问题的背景,与问题的技术答案无关。)vari a=b.a
如果我能像您在Java中那样“将其转换为A”,那就太好了。有没有更优雅的方法可以做到这一点。这对我来说很有效。虽然它不像您希望的那样直接转换,但它确实提供了正确的对象实例
fmt.Printf("It's", i.(B).A)
我希望它能帮上忙!这对我来说很有效。虽然它没有像你想要的那样直接施放,但它确实给出了正确的对象实例
fmt.Printf("It's", i.(B).A)
我希望它能有所帮助!如果您有未知的类型b,那么挖掘嵌入字段的唯一方法就是通过反射 没那么笨重: 结构嵌入不是继承,尝试这样使用它将继续带来类似的问题。在go中实现通用多态性的方法是使用接口
我认为处理这种情况最干净的方法是使用一个公共接口,为您想要处理的字段提供适当的访问器方法。您将在stdlib中看到这方面的示例,例如
http.ResponseWriter
,它有一个头()
用于访问实际响应头的方法。如果您有未知的类型b,则挖掘嵌入字段的唯一方法是通过反射
没那么笨重:
结构嵌入不是继承,尝试这样使用它将继续带来类似的问题。在go中实现通用多态性的方法是使用接口
我认为处理这种情况最干净的方法是使用一个公共接口,为您想要处理的字段提供适当的访问器方法。您将在stdlib中看到这方面的示例,例如
http.ResponseWriter
,它有一个头()
用于访问实际响应头的方法。我对它进行了一段时间的研究,我得到了以下结果:
我不能百分之百确定为什么会这样,但我最好的理论是,当你打电话的时候
a := i.(A)
您正在尝试对存储在i
到a
中的任何内容进行界面版本的类型转换。因此,您首先需要告诉它实际上是B
,然后您可以访问嵌套在其中的a
a := i.(B).A
玩了一会儿,我就成功了: 我不能百分之百确定为什么会这样,但我最好的理论是,当你打电话的时候
a := i.(A)
您正在尝试对存储在i
到a
中的任何内容进行界面版本的类型转换。因此,您首先需要告诉它实际上是B
,然后您可以访问嵌套在其中的a
a := i.(B).A
如果我能像你在Java中所做的那样“把它转换成一个”,那就太好了。有没有更优雅的方法可以做到这一点呢
对于代码质量来说,盲选几乎总是一个坏消息,所以它实际上是相当好的
使之难以做到
我会选择接口路径,因为它也会消除用于存储b
的接口{}
。
如果您确实拥有多种类型,并且它们只共享嵌入a
a接口的特性
它提供了AVal()A
对我来说很好
作为奖励,您可以直接在a
上定义AVal()a
,这样就不需要为嵌入a
的每种类型实现它
示例():
请注意,我现在使用的是指针值,因此AVal()*a
不会返回副本,而是
A
的相应实例
如果我能像你在Java中所做的那样“把它转换成一个”,那就太好了。有没有更优雅的方法可以做到这一点呢
对于代码质量来说,盲选几乎总是一个坏消息,所以它实际上是相当好的
使之难以做到
我会选择接口路径,因为它也会消除用于存储b
的接口{}
。
如果您确实拥有多种类型,并且它们只共享嵌入a
a接口的特性
它提供了AVal()A
对我来说很好
作为奖励,您可以直接在a
上定义AVal()a
,这样就不需要为嵌入a
的每种类型实现它
示例():
请注意,我现在使用的是指针值,因此AVal()*a
不会返回副本,而是
A
的相应实例使用i(B)断言i
为B
。之后,您可以从该断言值请求A
,因为它是B
的成员。这里没有魔法。遗憾的是,这要求您测试i
每种可能的类型,因为B
可能不是唯一具有A
的类型。因此此方法可能不是最好的。@nemo-是的,这正是di我遇到的困难。我不想让代码“知道”B,因为B实际上是在使用该包的另一个包中创建的