Использование базы встроенных типов в Go - PullRequest
0 голосов
/ 04 января 2019

Я новичок в Go и работаю с набором типов, сгенерированных gowsdl на основе определения NetSuite SuiteTalk веб-службы .Он создал следующие типы:

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, которая ищет BaseRef, что и являетсяRecordRef основан на.

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 голосов
/ 04 января 2019

Go не поддерживает полиморфизм таким образом, а также не поддерживает наследование так, как это делают C # или Java.Встроенные структуры буквально просто встроены, они не создают классическую иерархию наследования.Они просто передают в структуру-упаковку все открытые методы и поля встроенной структуры (с некоторыми тонкими предостережениями - посмотрите spec )

Тем не менее, в вашем примере RecordRefне относится к BaseRef с точки зрения его типа, вместо этого его можно считать «содержащим» указатель на BaseRef.Чтобы ваша программа компилировалась, вам нужно будет явно назначить встроенный BaseRef, например, так:

getRequest.BaseRef = &recordRef.BaseRef

Поскольку этот код, на который вы ссылаетесь, был автоматически сгенерирован из WSDL, он может быть немного громоздкимобновить GetRequest, чтобы обеспечить BaseRef подобную структуру данных более полиморфным, гибким способом, но для этого вам нужно будет использовать интерфейсы Go.

Вы можете обновить GetRequest, чтобы иметь метод с типами accept в типе интерфейса, скажем, XmlRef, который предоставит получатели, которые могут получить данные, которые вам нужно назначить для GetRequest

Например,

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

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

Затем просто реализуйте интерфейс для RecordRef и любых других структур, которые необходимо будет использовать в этом контексте.

0 голосов
/ 04 января 2019

Если я вас правильно понял, вы ищете способ доступа к встроенному полю struct.Вы можете просто использовать recordRef.BaseRef для этой цели.

Дальнейшее чтение: https://golang.org/ref/spec#Struct_types

...