在 Go 中使用嵌入式类型的基
Using base of embedded types in Go
我是 Go 的新手,正在使用 gowsdl based on the NetSuite SuiteTalk web service definition 生成的一组类型。它创建了以下类型:
type BaseRef struct {
XMLName xml.Name `xml:"urn:core_2018_2.platform.webservices.netsuite.com BaseRef"`
Name string `xml:"name,omitempty"`
}
type RecordRef struct {
XMLName xml.Name `xml:"urn:core_2018_2.platform.webservices.netsuite.com RecordRef"`
*BaseRef
InternalId string `xml:"internalId,attr,omitempty"`
ExternalId string `xml:"externalId,attr,omitempty"`
Type *RecordType `xml:"type,attr,omitempty"`
}
type GetRequest struct {
XMLName xml.Name `xml:"urn:messages_2018_2.platform.webservices.netsuite.com GetRequest"`
BaseRef *BaseRef `xml:"baseRef,omitempty"`
}
当我尝试使用这些类型时,我对在 GetRequest 结构中使用特定类型的引用记录的能力感到不满意,该结构正在寻找 RecordRef 所基于的 BaseRef。
var partnerRecordType RecordType
partnerRecordType = RecordTypePartner
recordRef := RecordRef{
Type:&partnerRecordType,
InternalId:internalIdString,
}
var getRequest GetRequest
getRequest.BaseRef = &recordRef
我在最后一行得到的错误是:
cannot use &recordRef (type *RecordRef) as type *BaseRef in assignment
对如何进行有任何想法吗?
如果我没理解错的话,您正在寻找一种方法来访问 struct
的嵌入字段。为此,您可以简单地使用 recordRef.BaseRef
。
Go 不以这种方式支持多态性,它也不以 C# 或 Java 的方式支持继承。嵌入式结构从字面上看只是嵌入式,它们不会创建经典的继承层次结构。它们只是将嵌入结构的所有公开方法和字段提供给包装结构(有一些微妙的注意事项 - 查看 spec)
就是说,在您的示例中,RecordRef
在类型方面与 BaseRef
无关,相反,它可以被视为 "contain" 指向 [=13= 的指针].为了让您的程序能够编译,您将像这样显式分配嵌入的 BaseRef
:
getRequest.BaseRef = &recordRef.BaseRef
由于您引用的这段代码是从 WSDL 自动生成的,因此更新 GetRequest
以提供更多态、更灵活的类似 BaseRef
的数据结构可能有点麻烦时尚,但为了做到这一点,你需要使用 Go 接口。
您可以将 GetRequest
更新为在接口类型中具有接受的方法,例如 XmlRef
这将公开可以导出您需要分配给 GetRequest
的数据的吸气剂
例如
type XmlRef interface {
Name() string
InternalID() string
ExternalID() string
}
func (r *GetRequest) SetRef(ref XmlRef) {
r.BaseRef.Name = ref.Name()
// etc...
}
然后简单地实现 RecordRef
的接口以及需要在此上下文中使用的任何其他结构。
我是 Go 的新手,正在使用 gowsdl based on the NetSuite SuiteTalk web service definition 生成的一组类型。它创建了以下类型:
type BaseRef struct {
XMLName xml.Name `xml:"urn:core_2018_2.platform.webservices.netsuite.com BaseRef"`
Name string `xml:"name,omitempty"`
}
type RecordRef struct {
XMLName xml.Name `xml:"urn:core_2018_2.platform.webservices.netsuite.com RecordRef"`
*BaseRef
InternalId string `xml:"internalId,attr,omitempty"`
ExternalId string `xml:"externalId,attr,omitempty"`
Type *RecordType `xml:"type,attr,omitempty"`
}
type GetRequest struct {
XMLName xml.Name `xml:"urn:messages_2018_2.platform.webservices.netsuite.com GetRequest"`
BaseRef *BaseRef `xml:"baseRef,omitempty"`
}
当我尝试使用这些类型时,我对在 GetRequest 结构中使用特定类型的引用记录的能力感到不满意,该结构正在寻找 RecordRef 所基于的 BaseRef。
var partnerRecordType RecordType
partnerRecordType = RecordTypePartner
recordRef := RecordRef{
Type:&partnerRecordType,
InternalId:internalIdString,
}
var getRequest GetRequest
getRequest.BaseRef = &recordRef
我在最后一行得到的错误是:
cannot use &recordRef (type *RecordRef) as type *BaseRef in assignment
对如何进行有任何想法吗?
如果我没理解错的话,您正在寻找一种方法来访问 struct
的嵌入字段。为此,您可以简单地使用 recordRef.BaseRef
。
Go 不以这种方式支持多态性,它也不以 C# 或 Java 的方式支持继承。嵌入式结构从字面上看只是嵌入式,它们不会创建经典的继承层次结构。它们只是将嵌入结构的所有公开方法和字段提供给包装结构(有一些微妙的注意事项 - 查看 spec)
就是说,在您的示例中,RecordRef
在类型方面与 BaseRef
无关,相反,它可以被视为 "contain" 指向 [=13= 的指针].为了让您的程序能够编译,您将像这样显式分配嵌入的 BaseRef
:
getRequest.BaseRef = &recordRef.BaseRef
由于您引用的这段代码是从 WSDL 自动生成的,因此更新 GetRequest
以提供更多态、更灵活的类似 BaseRef
的数据结构可能有点麻烦时尚,但为了做到这一点,你需要使用 Go 接口。
您可以将 GetRequest
更新为在接口类型中具有接受的方法,例如 XmlRef
这将公开可以导出您需要分配给 GetRequest
的数据的吸气剂
例如
type XmlRef interface {
Name() string
InternalID() string
ExternalID() string
}
func (r *GetRequest) SetRef(ref XmlRef) {
r.BaseRef.Name = ref.Name()
// etc...
}
然后简单地实现 RecordRef
的接口以及需要在此上下文中使用的任何其他结构。