54

我发现自己对arrayslice数据类型感到困惑。

在 Go 文档中,数组描述如下:

数组在 Go 和 C 中的工作方式之间存在重大差异。在 Go 中,

  • 数组是值。将一个数组分配给另一个数组会复制所有元素。
  • 特别是,如果将数组传递给函数,它将收到数组的副本,而不是指向它的指针。
  • 数组的大小是其类型的一部分。[10]int 和 [20]int 类型是不同的。

职能:

与 C 家族中的所有语言一样,Go 中的所有内容都是按值传递的。也就是说,一个函数总是得到一个被传递的东西的副本,就好像有一个赋值语句将值分配给参数一样。例如,将 int 值传递给函数会生成 int 的副本,传递指针值会生成指针的副本,但不会复制它指向的数据。

sort.Ints(arrayValue)当我将传递的变量声明为数组而不是切片时,为什么要修改它?

代码

var av = []int{1,5,2,3,7}

fmt.Println(av)
sort.Ints(av)
fmt.Println(av)
return

输出

[1 5 2 3 7]
[1 2 3 5 7]
4

5 回答 5

53

请参阅“切片:用法和内部

var av = []int{1,5,2,3,7}

那是一个切片,而不是一个数组。

切片文字的声明方式与数组文字一样,只是省略了元素计数。

这就解释了为什么排序函数会修改切片引用的内容。

正如Kirksort.Ints在下面评论的那样, 如果您将数组而不是切片传递给它,则会给您一个错误。

func Ints(a []int)
于 2012-07-31T09:39:17.087 回答
52

因为您使用的是切片,而不是数组。

那是一片:

var av = []int{1,5,2,3,7}

这些是数组:

var av = [...]int{1,5,2,3,7}
var bv = [5]int{1,5,2,3,7}

如果您尝试编译:

var av = [...]int{1,5,2,3,7}
fmt.Println(av)
sort.Ints(av)
fmt.Println(av)

,你会得到一个错误:

不能在函数参数中使用 av (type [5]int) 作为 type []int

因为 sort.Ints 期望收到一个切片 []int

于 2012-07-31T09:38:47.953 回答
11

[]int{1,5,2,3,7}不是数组。数组在其类型中具有长度,例如[5]int{1,5,2,3,7}.

制作切片的副本并对其进行排序:

a := []int{1,5,2,3,7}
sortedA := make([]int, len(a))
copy(sortedA, a)
sort.Ints(sortedA)
fmt.Println(a)
fmt.Println(sortedA)
于 2012-07-31T09:47:25.787 回答
3
var av = []int{1,5,2,3,7}

在上面的语句中,您正在像数组一样初始化切片

要创建一个数组,语法应该是

var av = [5]int{1,5,2,3,7}
于 2014-04-02T11:42:33.527 回答
2

切片是指向数组的指针。当您将一个数组复制到另一个数组或在函数中传递一个数组时,会复制或传递数组的整个副本。如果数组大小很大,这会使操作成本更高。所以我们可以去切片。

于 2019-01-18T06:57:04.440 回答