如何在golang中访问struct中的切片

问题描述 投票:-1回答:3

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

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

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

Car.Type[0] = 12
Car.Type[1] = 15
Car.Type[2] = 11
arrays go struct field
3个回答
3
投票

你把slice误认为是array。肯定是:

type Car struct {
    Year int
    Name string
    Type [3]int // <---
}

running code

你应该读一下这个旅游:https://tour.golang.org/moretypes/6


1
投票

如果尚未初始化切片字段,则无法直接访问切片字段。您正在定义一个包含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)

一些例子here


多一点背景。从广义上讲,切片和地图的工作方式类似。因为它们是内部依赖于指针的引用类型,所以具有切片作为返回类型的函数可以返回例如nil。这不适用于返回int的函数:

func nilSlice() []int {
    return nil
}

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

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

func nilInt() int {
    nil
}

产生的错误会说“不能将nil用作类型int”。将切片视为指针类型:它们需要在使用前安全地初始化。始终检查它们的长度,如果需要优化,请查看内置的append功能是如何实现的。它只是指数增长底层阵列的容量。你可能并不总是想要的东西。优化这种东西是微不足道的


-1
投票

你很困惑切片和数组。切片就像动态数组。您定义切片的方式,在追加它们之前不会定义它们的索引。对于上面的代码:

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类型的对象车。

© www.soinside.com 2019 - 2024. All rights reserved.