如何在Golang中的结构中访问切片

时间:2018-08-14 03:40:15

标签: arrays go struct field

如何访问结构内部定义的切片?

type Car struct {
    Year int
    Name string
    Type []int
}

//访问以下“类型”数组字段会导致错误:数组超出范围。

Car.Type[0] = 12
Car.Type[1] = 15
Car.Type[2] = 11

3 个答案:

答案 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)

一些示例here


更多背景信息。从广义上讲,切片和地图的工作方式相似。因为它们是引用类型,并且在内部依赖于指针,所以例如具有切片作为返回类型的函数可能会返回nil。这对于返回int的函数不起作用:

func nilSlice() []int {
    return nil
}

由于返回类型是切片,因此此函数将返回的内容实质上是一个空切片。访问它会导致发生相同的错误:索引超出范围。

尝试从这样的函数返回nil甚至不会编译:

func nilInt() int {
    nil
}

产生的错误将显示类似“不能将nil用作int类型” 。将切片视为指针类型:使用前需要对其进行安全初始化。始终检查它们的长度,如果需要优化,请查看内置append函数的实现方式。它只会成倍地增加基础数组的容量。您可能并不总是想要的东西。优化这种东西很简单

答案 2 :(得分:-1)

您混淆了切片和数组。切片就像动态数组。定义切片的方式只有在附加切片后才定义它们的索引。对于上面的代码:

temp->prev=s

此外,您的情况下 Car 是对象的类型而不是对象本身。我已声明类型为 Car 的对象 car