声明切片还是制作切片?

Wan*_* Yi 86 allocation go slice

在Golang,var s []int和之间有什么区别s := make([]int, 0)

我发现两者都有效,但哪一个更好?

fab*_*ioM 101

简单的声明

var s []int
Run Code Online (Sandbox Code Playgroud)

不分配内存和s指向nil,而

s := make([]int, 0)
Run Code Online (Sandbox Code Playgroud)

分配内存并s指向内存到具有0个元素的切片.

通常,如果您不知道用例的确切大小,则第一个更惯用.

  • 不,你需要`make`地图,因为即使是空的`map`也需要为一些簿记分配空间. (11认同)
  • 如果需要返回包含0个元素(而不是"nil")的切片,则make是正确的用法. (10认同)
  • 如果您正在构建API并返回一个数组作为响应,那么使用声明性表单将返回`nil`,以防您的切片没有任何元素,而不是空数组.但是,如果使用`make`来创建切片,则会返回一个空数组,这通常是所需的效果. (6认同)
  • 正如在这个答案的评论中所提到的:/sf/answers/2041519581/,在尝试执行像json marshaling这样的事情时会有所不同.对nil切片进行编组(`var s [] int`)将产生`null`,而对空切片进行编组(`s:= make([] int,0)`)将产生预期的`[]` (5认同)
  • 我可以对地图说同样的话吗?var m map[string]int 与 m:= make(map[string]int) ?谢谢。 (2认同)

Von*_*onC 86

除了fabriziom回答之外,您还可以在" Go Slices:usage and internals "中看到更多示例,其中[]int提到了一个用途:

由于slice(nil)的零值类似于零长度切片,因此您可以声明切片变量,然后在循环中追加它:

// Filter returns a new slice holding only
// the elements of s that satisfy f()
func Filter(s []int, fn func(int) bool) []int {
    var p []int // == nil
    for _, v := range s {
        if fn(v) {
            p = append(p, v)
        }
    }
    return p
}
Run Code Online (Sandbox Code Playgroud)

这意味着,要附加到切片,您不必首先分配内存:nil切片p int[]足以作为要添加的切片.

  • 我更倾向于在任何地方使用文字(例如`p := []int{}`)。由于我们通常使用 `:=` 语法来声明大多数变量,因此在任何地方都使用它比切片例外更自然。除此之外,尝试考虑分配通常会促使人们过早优化。 (2认同)

Ste*_*nov 14

刚发现有区别。如果你使用

var list []MyObjects
Run Code Online (Sandbox Code Playgroud)

然后你将输出编码为 JSON,你得到null.

list := make([]MyObjects, 0)
Run Code Online (Sandbox Code Playgroud)

结果[]如预期。

  • 是的,当我们想用 [] 数组而不是 null 进行响应时,后者非常有用 (4认同)

Ben*_*ari 5

更完整一点(在 中还有一个论点make)示例:

slice := make([]int, 2, 5)
fmt.Printf("length:  %d - capacity %d - content:  %d", len(slice), cap(slice), slice)
Run Code Online (Sandbox Code Playgroud)

出去:

length:  2 - capacity 5 - content:  [0 0]
Run Code Online (Sandbox Code Playgroud)

或者使用动态类型slice

slice := make([]interface{}, 2, 5)
fmt.Printf("length:  %d - capacity %d - content:  %d", len(slice), cap(slice), slice)
Run Code Online (Sandbox Code Playgroud)

出去:

length:  2 - capacity 5 - content:  [<nil> <nil>]
Run Code Online (Sandbox Code Playgroud)

  • 很好的例子。+1 (3认同)