【问题标题】:Setter method for slice struct in golanggolang中切片结构的setter方法
【发布时间】:2018-10-03 15:32:22
【问题描述】:

我有一个如下定义的支柱

type ReqJSON struct {
    Request struct {
        Data struct {
            Object struct {
                User []User `json:"user"`
            } `json:"object"`
        } `json:"data"`
    } `json:"request"`
}

type User struct {
    UserID string `json:"userid"`
    IPAddr string `json:"ipaddr"`
    Noofusers string `json:"noofusers"`
    Qos string `json:"qos"`
    ID string `json:"id"`
    Domain string `json:"domain"`
}

这个结构体的setter函数如下

func (j *ReqJSON) User() User     { return j.Request.Data.Object.User } 
func (j *ReqJSON) SetUser(u User) { j.Request.Data.Object.User = u }

主程序如下

func main() {
    var j ReqJSON
    j.SetUser(User{
            UserID:    "_id",
            IPAddr:    "1.1.1.1",
            Noofusers: "100",
            Qos:       "34",
            ID:        "kldjflkdfjlkdjfkld",
            Domain:    "xyz.com",
    })

    b, err := json.MarshalIndent(j, "", "  ")
    fmt.Println(err, string(b))
}

当我尝试将User 设为切片时,上述函数出现错误。

prog.go:27:65: 不能使用 j.Request.Data.Object.User (type []User) 作为 在返回参数 prog.go:28:64 中键入用户:不能使用 u(用户类型) 作为类型 [] 分配中的用户

我是 Golang 的新手,所以无法弄清楚如何让 Setter 和 Ctor 返回切片对象。

【问题讨论】:

  • 显示“将用户设为切片”的代码。
  • 显示失败的代码并提供您遇到的错误。
  • 我把它粘贴到了goplayground,没有报错:play.golang.org/p/VvuwHJShXBw你看到了什么错误?
  • 如果你使用更新的结构运行它会报错
  • @Abhinav 您没有将用户切片传递给 setter 函数,这就是错误的原因。

标签: go struct


【解决方案1】:

如果您将单个嵌入式用户结构更改为用户列表,则需要在任何地方进行更改。 Golang 是强类型的,用户切片与单个用户结构是不同的类型。以下代码有效

package main

import (
    "fmt"
    "encoding/json"
)

type ReqJSON struct {
    Request struct {
        Data struct {
            Object struct {
                User []User `json:"user"`
            } `json:"object"`
        } `json:"data"`
    } `json:"request"`
}

type User struct {
    UserID    string `json:"userid"`
    IPAddr    string `json:"ipaddr"`
    Noofusers string `json:"noofusers"`
    Qos       string `json:"qos"`
    ID        string `json:"id"`
    Domain    string `json:"domain"`
}

func (j *ReqJSON) User() []User     { return j.Request.Data.Object.User } 
func (j *ReqJSON) SetUsers(u []User) { j.Request.Data.Object.User = u }

func main() {

    var j ReqJSON
    j.SetUsers([]User{
    User{
        UserID:    "_id",
        IPAddr:    "1.1.1.1",
        Noofusers: "100",
        Qos:       "34",
        ID:        "kldjflkdfjlkdjfkld",
        Domain:    "xyz.com",
    },
    })

    b, err := json.MarshalIndent(j, "", "  ")
    fmt.Println(err, string(b))
}

【讨论】:

  • 在 OP 问题中没有与 Go 相关的内容是否为强类型。问题是 OP 没有在 setter 函数中传递用户片段。
  • 如果这是 python 或任何其他动态类型语言,将用户列表而不是单个用户传递给相同的实现就可以了。但是使用 go,您必须为所有内容指定参数和返回类型。这就是我提到打字的原因。
  • 在任何语言中,结构体和结构体数组之间存在很大差异。
  • 不正确。只要我不尝试做特定于数据结构的事情(即通过索引引用非数组的元素或通过名称引用非结构的成员)动态语言不在乎。如果我要在 python 中将数据结构转换为 json,我会使用 json.dumps(myobj) 并且不必指定 myobj 到底是什么,只要它是可序列化的。在 go 中,您必须指定所有内容的类型。
  • 我对 python 了解不多,但你错了,你不能将主要类型值分配给接受数组的变量。
【解决方案2】:

它显示错误,因为ReqJSON 结构包含User 的字段,这是User 结构的一个片段,但是当您为User 结构设置值时,您没有在内部传递用户结构的片段设置函数。

type ReqJSON struct {
    Request struct {
        Data struct {
            Object struct {
                User []User `json:"user"` // this is a slice of User struct
            } `json:"object"`
        } `json:"data"`
    } `json:"request"`
}

如果要初始化包含User 而不是User 切片的ReqJSON 结构内的字段,则需要在Setter 函数中传递一个用户结构切片。在 main 中传递 User 结构的切片为:

var u []User
u = append(u, User{
    UserID:    "_id",
    IPAddr:    "1.1.1.1",
    Noofusers: "100",
    Qos:       "34",
    ID:        "kldjflkdfjlkdjfkld",
    Domain:    "xyz.com",
})
j.SetUser(u)

Go Playground 上的工作代码

【讨论】:

    猜你喜欢
    • 2014-03-25
    • 1970-01-01
    • 1970-01-01
    • 2018-01-04
    • 2013-09-13
    • 2022-10-23
    • 2016-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多