【问题标题】:Go: declaring a slice inside a struct?Go:在结构中声明切片?
【发布时间】:2016-07-22 15:04:28
【问题描述】:

我有以下代码:

type room struct {
    width float32
    length float32
}
type house struct{
    s := make([]string, 3)
    name string
    roomSzSlice := make([]room, 3)
} 

func main() {


}

当我尝试构建和运行它时,我收到以下错误:

c:\go\src\test\main.go:10: syntax error: unexpected :=
c:\go\src\test\main.go:11: non-declaration statement outside function body
c:\go\src\test\main.go:12: non-declaration statement outside function body
c:\go\src\test\main.go:13: syntax error: unexpected }

我做错了什么?

谢谢!

【问题讨论】:

  • 只需像其他字段一样声明它。在这种情况下为“s []string”;该错误非常清楚地告诉您出了什么问题。
  • 谢谢,但是如果我像你说的那样声明,切片声明和数组声明有什么区别?
  • 一件事是数组的 type 的一部分是它的长度,所以 3 个元素的数组与 4 个元素的数组的类型不同,所以如果您声明一个数组,例如 var n [3]int,然后您有一个由 3 个整数组成的数组,切片与您编写的上下文相同:var []int,但没有给出长度。我想说的是不要担心数组;实际上,它们几乎在所有情况下都不是直接对我们有用。
  • make 确实允许您指定切片的长度和容量,但它们都可以更改。当你使用 make Go 创建一个未命名的数组并返回它的一个切片,这是你直接访问该数组的唯一方法。如果你超出了数组,那么 Go 可以为你创建一个新的、更大的数组,你的切片现在将指向它。
  • @Snowman 原谅我,但我不能同意数组没有直接用途的说法,更不用说在几乎所有情况下。对于任何基于固定大小的 IO,数组是唯一的方法。说到固定大小,我也想到了循环缓冲区。

标签: go struct slice


【解决方案1】:

你可以在结构声明中声明一个切片,但你不能初始化它。你必须通过不同的方式来做到这一点。

// Keep in mind that lowercase identifiers are
// not exported and hence are inaccessible
type House struct {
    s []string
    name string
    rooms []room
}

// So you need accessors or getters as below, for example
func(h *House) Rooms()[]room{
    return h.rooms
}

// Since your fields are inaccessible, 
// you need to create a "constructor"
func NewHouse(name string) *House{
    return &House{
        name: name,
        s: make([]string, 3),
        rooms: make([]room, 3),
    }
}

请以 runnable example on Go Playground

的形式查看上述内容

编辑

要部分初始化结构,按照 cmets 中的要求,可以简单地更改

func NewHouse(name string) *House{
    return &House{
        name: name,
    }
}

请再次将上述内容视为runnable example on Go Playground

【讨论】:

  • 谢谢,但是如果我不想初始化切片(意思是 - 我不想指定其中的元素数量),我该怎么做呢?
  • 只需删除 make 中的数字,例如 s: make([]string) 重新获取 tour.golang.org 可能是个好主意,并且阅读 Effective Go 肯定不会受到伤害,即使如果是第二次或第三次。
  • @MarkusWMahlberg 不起作用 - 需要切片长度作为 make 的参数。 @ Gambit2007 - 如果您不想初始化它,那么只需将其保留为零值(完全删除初始化)。它将为零,长度为 0。如果需要,您可以稍后对其进行初始化。
  • @joshlf 接受我自己的建议。谢谢。
  • 所以你的意思是这样的:s []string?那不就是一个数组声明吗?
【解决方案2】:

首先,您不能在结构内分配/初始化。 := 运算符声明和分配。但是,您可以简单地获得相同的结果。

这是一个简单的例子,可以大致完成您正在尝试的操作:

type house struct {
    s []string
}

func main() {
    h := house{}
    a := make([]string, 3)
    h.s = a
}

我从来没有这样写过,但如果它符合你的目的......它无论如何都会编译。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-27
    • 2018-12-05
    • 2014-04-02
    • 2013-08-05
    • 1970-01-01
    • 2019-01-28
    • 2022-12-05
    • 1970-01-01
    相关资源
    最近更新 更多