Initializing an empty array of struct type in golang

huangapple go评论101阅读模式
英文:

Initializing an empty array of struct type in golang

问题

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

type DayAndTime struct {
    days string
    time string
}

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

day := []DayAndTime{}

并且在其中放入了一个值:

day[0] = DayAndTime{"Monday", "8.00 PM"}

但是它显示了一个运行时错误:

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

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

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

英文:

I have initialized a struct :

type DayAndTime struct {
    days string
    time string
  }

I have initialized an empty set of array of this DayAndTime type:

day := []DayAndTime{}

And put a value in it:
day[0] = DayAndTime{"Monday", "8.00 PM"}

But it shows a runtime error:

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

Why is this happenning and what could be a possible solution?

edit: It's actually a slice not an array.

答案1

得分: 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()
}
英文:

Here you have a zero-length slice, the len and cap functions will both return 0 for a zero-valued slice

> A slice cannot be grown beyond its capacity. Attempting to do so will
> cause a runtime panic, just as when indexing outside the bounds of a
> slice or array. Similarly, slices cannot be re-sliced below zero to
> access earlier elements in the array.

You may us make to initialize the slice with capacity and assign with index or use append to add values to slice

Both are valid code

var day []DayAndTime
day = append(day, DayAndTime{"Monday", "8.00 PM"})

or

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

> Using append is recomended

Here is a sample code justifying/explaining the answer
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

得分: 0

如果你打印day的长度,你会得到0,所以你不能访问day[0],因为它不存在。

你可以这样写:day = append(day, DayAndTime{"Monday", "8.00 PM"})

英文:

If you print the length of day, you will get 0, so you cannot access day[0], which does not exist.

You can write it in this way: day = append(day, DayAndTime{"Monday", "8.00 PM"})

答案3

得分: 0

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

type DayAndTime struct {
    days string
    time string
}

days := []*DayAndTime{}
英文:

This should be the right syntax in your example:

type DayAndTime struct {
    days string
    time string
}

days := []*DayAndTime{}

答案4

得分: -1

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

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

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

无论如何,你得到了错误,因为在切片中,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)
}
英文:

You asked for a solution for arrays, but in your code you show a slice.

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

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

Anyway, ... you got that error because days[0] is out of range in the slice. Thant actually contains zero item and its length is zero. You have to use append, that return new slice, and then you can access to days[0]. Or can initialize with 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)
}

Another solution is to build an array instead of slice

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

huangapple
  • 本文由 发表于 2017年9月17日 15:04:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/46261548.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定