在golang中初始化一个空的结构体类型数组

22

我已经初始化了一个结构体:

type DayAndTime struct {
    days string
    time string
  }

我已经初始化了一个空的DayAndTime类型数组集合:

day := []DayAndTime{}

并且给它赋一个值:

day[0] = DayAndTime{"星期一", "晚上8点"}

但是它会显示运行时错误:

panic: runtime error: invalid memory address or nil pointer dereference

为什么会发生这种情况,可能的解决方案是什么?

编辑:实际上它是一个切片而不是一个数组。


1
https://tour.golang.org/moretypes/6 ff请访问上述链接,了解有关Go语言中切片的更多信息。 - Volker
5
不是数组,而是切片。 - sensorario
4个回答

34

在这里,您有一个长度为零的切片,lencap函数对于值为零的切片都将返回0

切片不能扩展到超出其容量的大小。如果尝试这样做,将导致运行时恐慌,就像访问切片或数组越界一样。同样,不允许将切片重新切片下限设为负数以访问数组中更早的元素。

您可以使用make初始化切片的容量,并使用索引分配值,也可以使用append向切片添加值

两者都是有效的代码

var day []DayAndTime
day = append(day, DayAndTime{"Monday", "8.00 PM"})
或者
var day = make([]DayAndTime, 1)
day[0] = DayAndTime{"Monday", "8.00 PM"}

建议使用append

这里是一个样例代码,用于证明/解释答案 https://play.golang.org/p/ajsli-6Vqw

package main

import (
    "fmt"
)

type DayAndTime struct {
    days string
    time string
}

func ZeroLength() {
    var day = []DayAndTime{}
    fmt.Println("Hello, playground", cap(day), len(day), day)
}

func AppendArray() {
    var day = []DayAndTime{}
    day = append(day, DayAndTime{"Monday", "8.00 PM"})
    fmt.Println("Hello, playground", cap(day), len(day), day)
}

func SetIndex() {
    var day = make([]DayAndTime, 1)
    day[0] = DayAndTime{"Monday", "8.00 PM"}
    fmt.Println("Hello, playground", cap(day), len(day), day)
}

func main() {
    ZeroLength()
    AppendArray()
    SetIndex()
}

2
day := []DayAndTime{} --- 这里并不是 nil - zerkms
@zerkms 是的,它是一个长度为零的切片。 - Sarath Sadasivan Pillai

0

这应该是您示例中的正确语法:

type DayAndTime struct {
    days string
    time string
}

days := []*DayAndTime{}

0
如果你打印day的长度,你会得到0,所以你不能访问不存在的day[0]
你可以这样写:day = append(day, DayAndTime{"星期一", "晚上8点"})

-1

你要求解决数组问题,但是在你的代码中展示的是一个切片。

foo := []string{}
t := reflect.TypeOf(foo)
fmt.Println(t.Kind()) // slice

bar := [2]string{}
tt := reflect.TypeOf(bar)
fmt.Println(tt.Kind()) // array

无论如何,...你之所以得到那个错误是因为在切片中days[0]超出了范围。实际上它不包含任何元素,其长度为零。你必须使用append来返回新的切片,然后才能访问days[0]。或者可以使用make进行初始化。
package main

import "fmt"

type DayAndTime struct {
    days string
    time string
}

func main() {
    days := []DayAndTime{}
    days = append(days, DayAndTime{"days ...", "time ..."})
    fmt.Printf("%v", days[0].days)
}

另一个解决方案是构建一个数组而不是切片。
func main() {
    days := [2]DayAndTime{}
    days[0].days = "fooo"
    fmt.Printf("%v", days[0].days)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接