如何访问结构中定义的切片?
type Car struct {
Year int
Name string
Type []int
}
//如下所示访问“类型”数组字段会导致错误:数组超出范围。
Car.Type[0] = 12
Car.Type[1] = 15
Car.Type[2] = 11
你把slice
误认为是array
。肯定是:
type Car struct {
Year int
Name string
Type [3]int // <---
}
你应该读一下这个旅游:https://tour.golang.org/moretypes/6
如果尚未初始化切片字段,则无法直接访问切片字段。您正在定义一个包含3个字段的结构:类型为int的Year
,这是一个简单的值,它是结构的一部分。同样适用于Name
。然而,Type
领域是一个切片。切片是参考类型。这意味着它本质上是一个隐藏的结构(称为切片头),其底层指针指向为您动态分配的数组。在您初始化变量时,这个底层指针是nil
。
type Car struct {
Year int
Name string
Type []int
}
可以看作:
type Car struct {
Year int
Name string
Type struct{
type: "int",
array *[]T
}
}
不完全是,但你明白了。当你写:
c := Car{}
您分配的只是int,string和slice标头。因此,您必须首先初始化切片:
c := Car{
Year: 2018,
Name: "vroom",
Type: []int{
1, 2, 3,
},
}
当然,有很多方法可以初始化切片。您不必仅设置值,但例如,您可以一次性分配和初始化所需的内存:
c.Type = make([]int, 3) // allocates an initialised 3 elements in the slice to 0
您也可以通过指定容量来分配但不初始化切片(这有助于避免重新分配和过于频繁地移动切片):
c.Type = make([]int, 0, 3)
或者,您可以使用append让运行时为您完成所有操作:
c.Type = append(c.Type, 1, 2, 3)
多一点背景。从广义上讲,切片和地图的工作方式类似。因为它们是内部依赖于指针的引用类型,所以具有切片作为返回类型的函数可以返回例如nil
。这不适用于返回int
的函数:
func nilSlice() []int {
return nil
}
因为返回类型是一个切片,所以此函数将返回的内容实际上是一个空切片。访问它将导致您发生相同的错误:索引超出范围。
试图从这样的函数返回nil甚至不会编译:
func nilInt() int {
nil
}
产生的错误会说“不能将nil用作类型int”。将切片视为指针类型:它们需要在使用前安全地初始化。始终检查它们的长度,如果需要优化,请查看内置的append
功能是如何实现的。它只是指数增长底层阵列的容量。你可能并不总是想要的东西。优化这种东西是微不足道的
你很困惑切片和数组。切片就像动态数组。您定义切片的方式,在追加它们之前不会定义它们的索引。对于上面的代码:
type Car struct {
Type []int
}
var car Car
car.Type = append(car.Type, 12)
car.Type = append(car.Type, 15)
car.Type = append(car.Type, 11)
此外,在您的情况下,汽车是一种对象而不是对象本身。我已经宣布了Car类型的对象车。