在Go中使用嵌入式类型库

时间:2019-01-03 23:31:11

标签: go suitetalk

我是Go语言的新手,正在使用gowsdl基于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

对如何进行有任何想法吗?

2 个答案:

答案 0 :(得分:1)

Go不以这种方式支持多态,也不以C#或Java的方式支持继承。嵌入式结构实际上只是嵌入式的,它们不会创建经典的继承层次结构。它们只是给包装结构提供了嵌入式结构的所有公开方法和字段(有一些细微的警告-请查看spec

也就是说,在您的示例中,RecordRefBaseRef的类型无关,而是可以认为它“包含”指向BaseRef的指针。为了使您的程序得以编译,您将像这样明确地分配嵌入式BaseRef

getRequest.BaseRef = &recordRef.BaseRef

由于您所引用的这段代码是从WSDL自动生成的,因此更新GetRequest以便以一种多态的,灵活的方式提供类似BaseRef的数据结构可能有点麻烦,但为此,您将需要使用Go接口。

您可以更新GetRequest,使其具有接口类型为accepts的方法,例如XmlRef,这将公开可以获取您需要分配给GetRequest的数据的吸气剂

例如

type XmlRef interface {
  Name() string
  InternalID() string
  ExternalID() string
}

func (r *GetRequest) SetRef(ref XmlRef) {
  r.BaseRef.Name = ref.Name()
  // etc...
}

然后只需为RecordRef和在此上下文中需要使用的任何其他结构实现接口。

答案 1 :(得分:0)

如果我理解正确,那么您正在寻找访问struct嵌入字段的方法。您可以为此简单地使用recordRef.BaseRef

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