Три точки содержат несколько значений?

Как я понимаю, "..." означает длину массива в приведенном ниже фрагменте.

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...)

Теперь, разница в этих двух значениях мешает мне понять, что такое "...".

Ответ 1

Вы отметили два случая ... в 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 ./... означает "проверить этот пакет и все пакеты в подкаталогах этого" Но мне должно быть ясно, что мое объяснение других использует, почему это имеет смысл здесь.)