三个点是否包含多种含义?

问题描述 投票:0回答:2

据我所知,“...”表示下面代码片段中数组的长度。

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

另一方面,正如我猜测的那样,“...”意味着将切片

y
解压到下面代码片段中的 int 参数。我对此不太确定。

x := []int{1,2,3}
y := []int{4,5,6}
x = append(x, y...)

现在,两种含义的差异让我很难理解“...”是什么。

go slice ellipsis
2个回答
32
投票

您已经注意到 Go 中

...
的两种情况。其实有3个:

[...]int{1,2,3}

在编译时将 计算为 [3]int{1,2,3}

a := make([]int, 500) SomeVariadicFunc(a...)

a

 解压为函数的参数。这与您错过的可变参数定义相匹配:

func SomeVariadicFunc(a ...int)

现在进一步的问题(来自OP的评论)——

为什么......在所有这些情况下都可以在语义上工作?答案是,在英语(和其他语言)中,这被称为“省略号”。从那篇文章 Ellipsis(复数省略号;源自古希腊语:ἔλλειψις, élleipsis,“遗漏”或“未达标”)是一系列点, 通常表示故意省略单词、句子或 文本的整个部分而不改变其原始含义。

1
根据其上下文和在句子中的位置,省略号可以 也表示未完成的想法、主要陈述、轻微的 停顿,以及紧张或尴尬的沉默。

在数组情况下,这符合“省略单词、句子或整个部分”的定义。您忽略了数组的大小并让编译器为您计算出来。

在可变参数情况下,它使用相同的含义,但不同。它还带有“未完成的想法”的暗示。我们经常使用“...”来表示“等等”。 “我要去买面包、鸡蛋、牛奶……”在这种情况下,“……”表示“类似于面包、鸡蛋和牛奶的其他东西”。例如,

append

中的使用表示“此列表的一个元素以及所有其他元素”。这也许是不太直观的用法,但对于母语人士来说,这是有道理的。也许更“语言纯粹”的构造是

a[0]...

 甚至 
a[0], a[1], a[2]...
 但这会导致空切片出现明显的问题(它确实与 
...
 语法一起使用),更不用说冗长了。
一般来说,“...”用来表示“许多事情”,这样它的两种用法都是有意义的。许多数组元素,许多切片元素(虽然一个是创建,另一个是调用)。

我想隐藏的问题是“这是好的语言设计吗?”一方面,一旦你了解了语法,它对于大多数以英语为母语的人来说都是完全有意义的,所以从这个意义上说它是成功的。另一方面,不以这种方式重载符号是有价值的。我可能会选择不同的符号来进行数组解包,但我不能责怪他们使用了语言设计者可能直观的符号。特别是因为数组版本甚至不经常使用。

如上所述,这对编译器来说不是问题,因为案例永远不会重叠。你永远不可能让

[...]

也意味着“解压这个”,所以不存在符号冲突。


(旁白:我省略了 Go 中它的另一种用法,因为它不在语言本身中,而是在构建工具中。输入类似

go test ./...
的内容意味着“测试这个包,以及这个包的子目录中的所有包”。但通过我对其他用途的解释应该非常清楚为什么它在这里有意义。)


仅供参考,

0
投票

not

 意味着“解压”输入
s
相反,“绕过”会更合适。

如果

s

是切片

s := []string{"a", "b", "c"}

,
myfunc(s...)

不等于

 
myfunc(s[0], s[1], s[2])
这个简单的代码

显示了它。

另外,请参阅官方

Go 规范
(为清楚起见略有修改):

鉴于功能

func Greeting(prefix string, who ...string)

如果最后一个参数可分配给切片类型 []T 并且是
后跟 
...

,它作为 ...T 的值不变地传递 范围。在这种情况下,

不会创建新切片。


给定切片 s 并调用

s := []string{"James", "Jasmine"}

Greeting("goodbye:", s...)

在 Greeting 中,
who

将与 s 具有相同的值,并且具有相同的基础 数组。


如果它“解压”输入参数,则应创建一个具有 different

数组的新切片(事实并非如此)。

注意:这不是真正的“绕过”,因为切片本身(而不是底层数组)被复制到函数中(Go 中没有“引用”)。但是,函数中的切片指向相同的原始底层数组,因此它是比“解包”更好的描述。

© www.soinside.com 2019 - 2024. All rights reserved.