x := […]string{"Sat", "Sun"} vs x:= []string{"Sat", "Sun"}

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

x := [...]string{"Sat", "Sun"} vs x:= []string{"Sat", "Sun"}

问题

在Go语言的规范中,它们在一个示例中使用了三个点:

days := [...]string{"Sat", "Sun"}  // len(days) == 2

如果省略这三个点,会有什么区别吗?

英文:

In the go lang spec they used three dots in one of the examples:

days := [...]string{"Sat", "Sun"}  // len(days) == 2

Does it make any difference if the three dots are left out?

答案1

得分: 31

这里是翻译的结果:

这有一个相当大的区别:这个区别在于arrayslice之间。

[]string创建一个指向字符串数组的切片。另一方面,[...]创建一个实际的字符串数组。

关于这两者之间的区别,golang博客上有一篇很棒的博文。我会尽力在这里进行总结。

在golang中,数组就像值类型一样,它们是指向特定类型的引用,并且始终具有特定的长度。有两种创建数组的方式:1)使用显式长度和2)隐式长度:

// 显式长度。
var days := [7]string { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }

// 隐式长度。(让编译器自己计算长度)
var days := [...]string { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" } 

这两种定义数组的方式是等价的。请注意,数组的长度是其类型定义的一部分。因此,不能用不同长度的相似类型的数组进行交换:

// 这两个是不能互换的!
var someArray [5]string;
var otherArray [10]string;

func work(data [5]string) { /* ... */ }

work(someArray)  // 可以
work(otherArray) // 不太好

还要注意,数组和结构体一样,是按值传递的——函数将获得数组的副本,而不是引用。

另一方面,切片就像引用类型一样。它们由一个指向数组中某个位置的指针、一个长度和一个容量组成。

// 创建一个切片
var days := []string { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }

与数组不同,切片并没有显式地绑定其长度,不同长度的切片可以互相传递。它们也更像指针,这意味着它们是通过引用传递的,而不是值传递。

还有一篇关于Go数据结构的很棒的文章,介绍了它们在内存中的表示方式。我强烈推荐去看一下。

英文:

It makes a pretty big difference: The difference is between an array and a slice.

[]string creates a slice that points to an array of strings. On the other hand, [...] creates an actual array of strings.

There is a great blog post about the difference between the two on the golang blog. I'll try to summarize here as best I can.

Arrays in golang are like value types, they are references to a specific type and are always of a specific length. There are two ways to create an array: 1) with explicit length and 2) implicit length:

// Explicit length. 
var days := [7]string { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }

// Implicit length. (Let the compiler figure it out how long it is)
var days := [...]string { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" } 

These are both equivalent array definitions. Note that the length of an array is part of it's type definition. So, you can't interchange arrays of similar type with different lengths:

// These two are not interchangeable!
var someArray [5]string;
var otherArray [10]string;

func work(data [5]string) { /* ... */ }

work(someArray)  // good
work(otherArray) // not so good

Also note that arrays, like structs, are passed as value – a copy of the array will be given to a function, not a reference to it..

Slices, on the other hand, are like reference types. They are backed by an array, but they are more malleable. They include a pointer to a position within array, a length, and a capacity.

// Create a slice
var days := []string { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }

Slices, unlike arrays, are not explicitly bound to their length and slices of different lengths can be passed for one another. They also act more like a pointer, which means they get passed by reference, instead of value.

There is also a great post about Go Data Structures, and how they are they are represented in memory. I highly recommend checking it out.

huangapple
  • 本文由 发表于 2013年11月28日 07:05:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/20254834.html
匿名

发表评论

匿名网友

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

确定