数组和切片数据类型

huangapple go评论104阅读模式
英文:

Array and slice data types

问题

我发现自己对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]
英文:

I found myself confused with the array and slice data types.

From Go docs, arrays are described as follows:

> There are major differences between the ways arrays work in Go and C. In Go,
>
> - Arrays are values. Assigning one array to another copies all the elements.
> - In particular, if you pass an array to a function, it will receive a copy of the array, not a pointer to it.
> - The size of an array is part of its type. The types [10]int and [20]int are distinct.

Functions:

> As in all languages in the C family, everything in Go is passed by
> value. That is, a function always gets a copy of the thing being
> passed, as if there were an assignment statement assigning the value
> to the parameter. For instance, passing an int value to a function
> makes a copy of the int, and passing a pointer value makes a copy of
> the pointer, but not the data it points to.

Why does sort.Ints(arrayValue) modify the passed variable when I declared it as an array, not as a slice?

Code

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

Output

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

答案1

得分: 55

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

这是一个切片:

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)

你会得到一个错误:

> cannot use av (type [5]int) as type []int in function argument

因为sort.Ints期望接收一个<a href="http://golang.org/pkg/sort/#Ints">切片 []int</a>。

英文:

Because you're using a slice, not an array.

That is a slice:

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

And those are arrays:

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

If you try to compile:

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

, you will get an error:

> cannot use av (type [5]int) as type []int in function argument

as sort.Ints expects to receive a <a href="http://golang.org/pkg/sort/#Ints">slice []int</a>.

答案2

得分: 55

参见“切片:用法和内部原理

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

这是一个切片,不是一个数组。

切片字面量的声明方式与数组字面量相同,只是省略了元素数量。

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

正如下面由Kirk评论所述,如果你传递给sort.Ints一个数组而不是一个切片,它会报错。

func Ints(a []int)
英文:

See "Slices: usage and internals"

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

That is a slice, not an array.

> A slice literal is declared just like an array literal, except you leave out the element count.

That explains why the sort function will modify the content of what is referenced by the slice.

As commented below by Kirk, sort.Ints will give you an error if you passed it an array instead of a slice.

func Ints(a []int)

答案3

得分: 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)
英文:

[]int{1,5,2,3,7} is not an array. An array has it's length in it's type, like [5]int{1,5,2,3,7}.

Make a copy of the slice and sort it instead:

a := []int{1,5,2,3,7}
sortedA := make([]int, len(a))
copy(sortedA, a)
sort.Ints(sortedA)
fmt.Println(a)
fmt.Println(sortedA)

答案4

得分: 5

切片是指向数组的指针。当你将一个数组复制到另一个数组,或者当你将一个数组传递给函数时,整个数组的副本被复制或传递。如果数组的大小很大,这将导致更昂贵的操作。因此,我们可以使用切片。

英文:

slices are pointer to array . when you copy an array to another or when you pass a array in the function the entire copy of array is copied or passed . This makes a costlier operation if thae array size is large. so we can go for slices.

答案5

得分: 3

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

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

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

in the above statement you are initializing slice like an array

To create an array the syntax should be

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

huangapple
  • 本文由 发表于 2012年7月31日 17:29:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/11737053.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定