【问题标题】:How to initialize values for nested struct array in golang如何在golang中初始化嵌套结构数组的值
【发布时间】:2015-11-24 11:35:27
【问题描述】:

我的结构

type Result struct {
   name   string
   Objects []struct {
       id int
   }
}

为此初始化值

func main() {
   var r Result;
   r.name  = "Vanaraj";
   r.Objects[0].id = 10;
   fmt.Println(r)
}

我收到了这个错误。 “恐慌:运行时错误:索引超出范围”

如何解决这个问题?

【问题讨论】:

    标签: go


    【解决方案1】:

    首先,我想说为你的结构定义一个类型更符合习惯,不管结构有多简单。例如:

    type MyStruct struct {
        MyField int
    }
    

    这意味着将您的 Result 结构更改为如下:

    type Result struct {
        name   string
        Objects []MyStruct
    }
    

    您的程序出现恐慌的原因是您试图访问尚未分配的内存区域(Objects 数组中的一项)。

    对于结构数组,这需要使用make 来完成。

    r.Objects = make([]MyStruct, 0)
    

    然后,为了安全地添加到您的数组中,您最好实例化一个 MyStruct,即

    ms := MyStruct{
        MyField: 10,
    }
    

    然后将 append 发送到您的 r.Objects 数组

    r.Objects = append(r.Objects, ms)
    

    有关make的更多信息,请参阅the docs

    【讨论】:

    • 长度必须在make中指定,不是吗? make([]MyStruct, 0)
    • 有没有办法不用重构代码来初始化Objects数组
    • @Katiyman 如果您的意思是要初始化一个包含 10 个对象的列表,我认为您可以使用 r.Objects = make([]MyStruct, 10)
    【解决方案2】:

    按照another answer 中的建议定义结构后:

    type MyStruct struct {
        MyField int
    }
    
    
    type Result struct {
        Name   string
        Objects []MyStruct
    }
    

    然后你可以像这样初始化一个Result对象:

    result := Result{
        Name: "I am Groot",
        Objects: []MyStruct{
            {
                MyField: 1,
            },
            {
                MyField: 2,
            },
            {
                MyField: 3,
            },
        },
    }
    

    完整代码:

    package main
    
    import "fmt"
    
    func main() {
        result := Result{
            Name: "I am Groot",
            Objects: []MyStruct{
                {
                    MyField: 1,
                },
                {
                    MyField: 2,
                },
                {
                    MyField: 3,
                },
            },
        }
    
        fmt.Println(result)
    
    }
    
    type MyStruct struct {
        MyField int
    }
    
    type Result struct {
        Name    string
        Objects []MyStruct
    }
    

    您可以在此Go playground 中验证这一点。

    【讨论】:

    • 我想知道是否可以使用 make:Objects: make([]MyStruct, 0, 10) 初始化数组对象,以便将其初始化为切片?
    【解决方案3】:

    Objects 不包含任何元素。您需要先append 元素。像这样:

    r.Objects = append(r.Objects, struct{ id int }{}) 
    

    你也可以像这样使用你的结构初始化来省略r.Objects[0].id = 10;

    r.Objects = append(r.Objects, struct{ id int }{ 10 })
    

    【讨论】:

    • 感谢 Ronindev。 type Result struct { name string Objects []struct { id int name string email string } } 如何为此添加值?
    • RobinDev,如何追加多个变量?
    • @vanarajcs 类似r.Objects = append(r.Objects, struct{ id int }{10}, struct{ id int }{20})
    • 最好为struct{ id int } 使用命名类型,正如@matt-schofield 建议的那样
    • r.Objects = append(r.Objects, struct{ id int, string name}{ 10 "Vanaraj"}) 对吗?
    【解决方案4】:

    这可能是一个愚蠢的想法,但你可以通过 JSON 来回它:

    package main
    
    import (
       "bytes"
       "encoding/json"
    )
    
    type (
       a []interface{}
       m map[string]interface{}
    )
    
    func decode(in, out interface{}) {
       var b bytes.Buffer
       json.NewEncoder(&b).Encode(in)
       json.NewDecoder(&b).Decode(out)
    }
    

    例子:

    package main
    import "fmt"
    
    type result struct {
       Name string
       Objects []struct {
          Id int
       }
    }
    
    func main() {
       r := m{
          "Name": "Vanaraj",
          "Objects": a{
             m{"Id": 10},
          },
       }
       var s result
       decode(r, &s)
       fmt.Printf("%+v\n", s) // {Name:Vanaraj Objects:[{Id:10}]}
    }
    

    【讨论】:

      猜你喜欢
      • 2015-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多