В чем разница между [] строка и… строка в голанге?


85

На языке Go

[]string это строковый массив

и мы также используем ...stringв качестве параметра.

В чем разница?

Определение функции:

func f(args ...string) {}

Могу ли я вызвать эту функцию, как показано ниже?

args := []string{"a", "b"}

f(args)

Ответы:


126

[]string это строковый массив

Технически это фрагмент, который ссылается на базовый массив

и мы также используем ...stringв качестве параметра.

В чем разница?

Что касается конструкции, то ничего особенного. Тип данных, полученный в результате обоих синтаксисов, одинаков.

...Синтаксис параметра делает VARIADIC параметр. Он будет принимать ноль или более stringаргументов и ссылаться на них как на срез.

Что касается вызова f, вы можете передать фрагмент строк в вариативный параметр со следующим синтаксисом:

func f(args ...string) {
    fmt.Println(len(args))
}


args := []string{"a", "b"}

f(args...)

Этот синтаксис доступен либо для фрагмента, построенного с использованием буквального синтаксиса, либо для фрагмента, представляющего переменный параметр (поскольку на самом деле между ними нет никакой разницы) .

http://play.golang.org/p/QWmzgIWpF8


10
[]stringэто срез, а не массив. Различия между массивом и срезом тонкие, но важные.
Стивен Вайнберг

@StephenWeinberg: Да, мой ответ «ничего особенного» на цитату «в чем разница» - это ответ на вопрос, который был задан о разнице между срезом, сгенерированным параметром вариативной функции, и срезом, созданным с использованием []stringсинтаксиса. Я добавлю цитату к своему ответу, чтобы было понятнее. :-)
I Hate Lazy

@IHateLazy Есть ли способ заставить встроенный printlnработать с многоточием? Здесь вы можете найти мои эксперименты. Если кому-то нужны отладочные функции печати, сходите и посмотрите мою игру.
хранилище

14

Оба создают массив строк, но разница в том, как он называется.

func f(args ...string) {

}
// Would be called like this:

f("foo","bar","baz");

Это позволяет вам принимать переменное количество аргументов (все одного типа)

Прекрасным примером этого являются fmt.Printи друзья, которые могут принять столько лекарств, сколько захотите.


Я не эксперт по Go, но разве один из вариативных аргументов, а другой не является аргументом единственного массива, и разве эти два не отличаются, как в других языках?
Гонки легкости на орбите

1
@LightnessRacesinOrbit Ага. Если это не ясно, извините за недоразумение. Первая строка о создании массива в обоих случаях означает, что результирующий аргумент в обоих экземплярах является массивом. Он почти идентичен def fn(*args)конструкции Python .
Тайлерл

Итак, Go предоставляет вариативные аргументы как экземпляр типа массива? Это приятно.
Гонки легкости на орбите

На самом деле они оба создают кусочек строк, а не массив. В голанге это разные вещи.
PointerToConstantChar

Оба не создают «массив» строк, они создают «кусочек» строк.
Inanc Gumus


1

Это упрощает параметры вашей функции. Вот пример ( https://play.golang.org/p/euMuy6IvaM ): Метод SampleEllipsis принимает от нуля до многих параметров одного и того же типа, но в методе SampleArray обязательно должны быть объявлены аргументы .

package main

import "fmt"

func SampleEllipsis(args ...string) {
    fmt.Printf("Sample ellipsis : %+v\n",args)
}


func SampleArray(args []string) {
    fmt.Println("Sample array ")
    SampleEllipsis(args...)
}

func main() {
    // Method one
    SampleEllipsis([]string{"A", "B", "C"}...)
    // Method two
    SampleEllipsis("A", "B", "C")
    // Method three
    SampleEllipsis()

    // Simple array
    SampleArray([]string{"A", "B", "C"})

    // Simple array
    SampleArray([]string{})

}

Возврат:

Sample ellipsis : [A B C]
Sample ellipsis : [A B C]
Sample ellipsis : []
Sample array 
Sample ellipsis : [A B C]
Sample array 
Sample ellipsis : []
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.