【问题标题】:Auto create instances of a struct自动创建结构的实例
【发布时间】:2018-08-10 08:36:38
【问题描述】:

我正在运行一段通过 MQTT 接收 JSON 的代码。每次收到 JSON(MQTT 始终在运行)时,我都想创建一个我拥有的结构的实例。我还想将该实例附加到列表中,以跟踪我拥有的实例数量。

这是我目前所拥有的:

func VirtualDevice(client MQTT.Client, deviceID string) **VirtualDevice {
    type Device struct{
        Type        string `json:"type"`
        Value       []interface{} `json:"value"`
        CaptureTime string   `json:"capture-time"`
    }
    type VirtualDevice struct {
        Passport struct {
            MessageTopic string `json:"message-topic"`
            PrivateKey   string `json:"private-key"`
        } `json:"passport"`
        Data struct {
            Sensor []Device `json:"sensor"`
            Actuator struct {
            } `json:"actuator"`
        } `json:"data"`
    }

    sensorData := new(VirtualDevice)

    var g MQTT.MessageHandler = func(client MQTT.Client, msg MQTT.Message) {
        err := json.Unmarshal(msg.Payload(), &sensorData)
        if err != nil {
            panic(err)
        } else {
            fmt.Printf("%+v\n", sensorData) //data_update    
        }
    }
    client.Subscribe("data-update/" + deviceID, 0, g)
    return &sensorData //Error: Cannot use &sensorData (type **VirtualDevice) as type **VirtualDevice
}

在另一个文件中,我有这个:

type Ctrl struct {
    Instance []*VD
}   
var device *VD
if len(sensorList.Instance) == 0 {
            device = VirtualDevice(client, deviceID)
            oldDeviceID = deviceID
            sensorList.Instance = append(sensorList.Instance, device)
        }else if oldDeviceID != deviceID{
            device = VirtualDevice(client, deviceID)
            sensorList.Instance = append(sensorList.Instance, device)

        }
        fmt.Println(*sensorList.Instance[0])

如您所见,我无法返回&sensor,即使它是**VirtualDevice 类型。我怎样才能返回这个,我是否在正确的轨道上实现我想要实现的目标? (为每个传入的 JSON 创建相同结构的新实例,并为每个实例附加一个指针以不丢失数据)

编辑:我能够成功返回结构,但是当我打印出*sensorList.Instance[0] 时,我得到一个空的 JSON。我究竟做错了什么?

【问题讨论】:

  • 不确定这里的问题 - Go Tour 中全面介绍了基本语法:tour.golang.org/welcome/1
  • 您创建结构类型的值与在代码的任何其他部分中创建的值相同。我真的不确定你在问什么,因为你显示的唯一一段代码是 if 声明。
  • 结构初始化在tour.golang.org/moretypes/5。如果你是新手,你应该参加整个旅程。
  • 对不起,如果我不清楚。我知道如何创建结构的实例。但我想要它,所以每次收到消息时,都会自动创建一个结构。我应该分配内存并将一个点附加到列表中的该结构吗?
  • 这是编程,不是魔术。没有任何事情会自动发生。作为程序员,您必须确定会发生什么以及在什么情况下发生。现在,“发生了什么”还不够清楚,无法编写任何代码。因此,当您“接收 JSON”时,您将调用一些代码来创建一个结构。 @Peter 已经为您提供了创建新结构实例的语法。为什么不能接受?你真正想要发生什么?

标签: go struct


【解决方案1】:

您的函数无法返回 **VirtualDevice,因为该类型的作用域是函数。将type 定义移到func 之外。如果它们已经在外部定义,只需删除它们。

另外,我认为您可能对指针有点困惑。 new(VirtualDevice) 返回一个指向新创建的VirtualDevice 的指针,(所以你的sensorData*VirtualDevice 类型)。当您使用&sensorData 时,您将获得该指针的指针。你通常不想这样做。您可以不将 & 传递给 json.Unmarshal 并返回并更改返回类型。

【讨论】:

  • 谢谢。我还试图将指向我的 VirtualDevice 结构的指针附加到一个指针片中。但是,当我打印出该切片的第一个元素时,我得到一个空 JSON。关于为什么会这样的任何想法?
  • fmt.Println 不打印 JSON。它通过各种方式将值转换为字符串。默认情况下,指针作为内存地址打印出来。我在您的示例中没有看到 VD 类型,但您可以尝试向其中添加 func (vd *VD) String() string 并查看这是否会改变您的输出。
  • 它目前打印出这个:{{ } {[] {}}} 问题是它在填写任何信息之前打印出来。有什么办法可以让程序停在我的第二个文件中?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-02
  • 2021-10-11
  • 2013-07-20
  • 1970-01-01
  • 2022-12-03
  • 2014-09-06
相关资源
最近更新 更多