在 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

进一步阅读:https://golang.org/ref/spec#Struct_types

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 的接口以及需要在此上下文中使用的任何其他结构。