如何访问结构内部定义的切片?
type Car struct {
Year int
Name string
Type []int
}
//访问以下“类型”数组字段会导致错误:数组超出范围。
Car.Type[0] = 12
Car.Type[1] = 15
Car.Type[2] = 11
答案 0 :(得分:3)
您将slice
误认为array
。它必须是:
type Car struct {
Year int
Name string
Type [3]int // <---
}
请参见https://www.spinnaker.io/guides/user/pipeline/expressions/#property-files
您应该阅读此导览:running code
答案 1 :(得分:1)
如果未初始化切片字段,则无法直接访问它。您定义的结构具有3个字段:Year
类型为int,这是结构的一部分,是一个简单的值。 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,字符串和切片 header 。因此,您必须先初始化切片:
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
函数的实现方式。它只会成倍地增加基础数组的容量。您可能并不总是想要的东西。优化这种东西很简单
答案 2 :(得分:-1)
您混淆了切片和数组。切片就像动态数组。定义切片的方式只有在附加切片后才定义它们的索引。对于上面的代码:
temp->prev=s
此外,您的情况下 Car 是对象的类型而不是对象本身。我已声明类型为 Car 的对象 car 。