如何定义具有不同字段类型的 GoLang 结构

我对GoLang比较陌生,并且在严格的类型系统中遇到了麻烦(我更习惯于弱类型语言)。


在尝试编写Alexa智能家居技能时,我需要创建定义(例如)的JSON结构 https://developer.amazon.com/en-US/docs/alexa/device-apis/alexa-contactsensor.html


国家报告回应是我开始遇到麻烦的地方,特别是在上下文中。


该示例如下所示:


  "context": {

    "properties": [

      {

        "namespace": "Alexa.ContactSensor",

        "name": "detectionState",

        "value": "NOT_DETECTED",

        "timeOfSample": "2017-02-03T16:20:50.52Z",

        "uncertaintyInMilliseconds": 0

      },

      {

        "namespace": "Alexa.EndpointHealth",

        "name": "connectivity",

        "value": {

          "value": "OK"

        },

        "timeOfSample": "2017-02-03T16:20:50.52Z",

        "uncertaintyInMilliseconds": 0

      }

    ]

  }

乍一看,这看起来很简单:


    Context struct {

        Properties []struct {

            Namespace                 string    `json:"namespace"`

            Name                      string    `json:"name"`

            Value                     string    `json:"value"`

            Timeofsample              time.Time `json:"timeOfSample"`

            Uncertaintyinmilliseconds int       `json:"uncertaintyInMilliseconds"`

        } `json:"properties"`

    } `json:"context"`

但是“值”字段是我遇到问题的地方。


在数组的第一个元素中,我们有一个简单的字符串


        "value": "NOT_DETECTED",

但第二个元素是一个结构


        "value": {

          "value": "OK"

        },

(这似乎不是文档中的拼写错误;它在 https://developer.amazon.com/en-US/docs/alexa/device-apis/alexa-endpointhealth.html 和其他地方也重复出现)。


这就是GoLang的严格输入和我对语言的了解开始击败我的地方。


如何对此元素进行建模,因为它似乎没有固定类型?value


还是有更好的方法来做到这一点?


慕虎7371278
浏览 70回答 2
2回答

梦里花落0921

创建一个类似如下的类型:import (    "bytes"    "encoding/json"    "fmt")// nullOK is a JSON OK literalvar nullOK = []byte("OK")type ValueString struct {    Error string    Valid bool}// UnmarshalJSON implements json.Unmarshaler.func (s *ValueString) UnmarshalJSON(data []byte) error {    if bytes.Equal(data, nullOK) {        s.Valid = true        return nil    }    if err := json.Unmarshal(data, &s.Error); err != nil {        return fmt.Errorf("checking OK: couldn't unmarshal JSON: %w", err)    }    s.Valid = false    return nil}// MarshalJSON implements json.Marshaler.func (s ValueString) MarshalJSON() ([]byte, error) {    if s.Valid {        return []byte("OK"), nil    }    return json.Marshal(s.Error)}并在您的结构中使用它:...Value                     ValueString    `json:"value"`...当值为“OK”时,您的将是 ,否则请检查解析值。Value.ValidtrueValue.Error

泛舟湖上清波郎朗

使用mkopriva的提示,我想我提出了使用和匿名结构的简单概念验证解决方案interface{}package mainimport "encoding/json"import "fmt"type Foo struct {        Value interface{} `json:"value"`}func main() {        v1 := Foo{Value: "version1"}        j1, _ := json.Marshal(v1)        fmt.Println(string(j1))        v2 := Foo{Value: struct {                Value string `json:"value"`        }{Value: "version2"}}        j2, _ := json.Marshal(v2)        fmt.Println(string(j2))}运行此命令会得到两个输出:{"value":"version1"}{"value":{"value":"version2"}}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go