Яка різниця між рядком [] та… рядком у голангу?


85

Мовою Go,

[]string - це масив рядків

і ми також використовуємо ...stringяк параметр.

Яка різниця?

Визначення функції:

func f(args ...string) {}

Чи можу я викликати цю функцію, як показано нижче?

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

f(args)

Відповіді:


126

[]string - це масив рядків

Технічно це фрагмент, який посилається на базовий масив

і ми також використовуємо ...stringяк параметр.

Яка різниця?

Що стосується структури, то насправді нічого. Тип даних, отриманий з обох синтаксисів, однаковий.

...Синтаксис параметра робить VARIADIC параметр. Він прийме нуль або більше stringаргументів і посилатиметься на них як на фрагмент.

Що стосується виклику f, ви можете передати фрагмент рядків у параметр variadic із таким синтаксисом:

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


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

f(args...)

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

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


10
[]stringє фрагментом, а не масивом. Відмінності між масивом та фрагментом незначні, але важливі.
Стівен Вайнберг,

@StephenWeinberg: Так, моя відповідь "нічого насправді" на цитату "в чому різниця" відповідає на запитання про різницю між зрізом, згенерованим параметром варіатичної функції, і тим, що створений із використанням []stringсинтаксису. Я додаю ще цитату до своєї відповіді, щоб вона стала зрозумілішою. :-)
Я ненавиджу лінивого

@IHateLazy Чи є спосіб змусити вбудовану printlnроботу з еліпсисом? Тут ви можете знайти мої експерименти. Якщо хтось бажає певних функцій друку налагодження, перейдіть дивитись моє програвання.
сховище

14

Обидва створюють масив рядків, але різниця полягає в тому, як він називається.

func f(args ...string) {

}
// Would be called like this:

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

Це дозволяє приймати змінну кількість аргументів (усіх одного типу)

Прекрасним прикладом цього є fmt.Printі друзі, які можуть прийняти скільки завгодно або стільки порушень.


Я не фахівець із Go, але чи не є один варіативний аргумент, а інший - єдиним аргументом масиву, і чи не відрізняються ці два як в інших мовах?
Гонки легкості на орбіті

1
@LightnessRacesinOrbit Yup. Якщо це незрозуміло, то вибачте за плутанину. Перший рядок про обидва створення масиву просто означає, що результативним аргументом в обох примірниках є масив. Це майже ідентично def fn(*args)конструкції python .
tylerl

Тож 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.