Подтвердить что ты не робот

Тип данных пары/кортежа в Go

Выполняя окончательное упражнение Tour of Go, я решил, что мне нужна очередь (string, int)., Это достаточно легко:

type job struct {
    url string
    depth int
}

queue := make(chan job)
queue <- job{url, depth}

Но это заставило меня задуматься: есть ли встроенные типы данных пары/кортежа в Go? Существует поддержка возврата нескольких значений из функции, но AFAICT, полученные множественные кортежи, не являются первоклассными гражданами в системе типа Go. Это тот случай?

Что касается части "что вы пробовали", то очевидный синтаксис (от POV-программиста POV)

queue := make(chan (string, int))

не работает.

4b9b3361

Ответ 1

В Go нет типа кортежа, и вы правы, множественные значения, возвращаемые функциями, не представляют объект первого класса.

Ответ Nick показывает, как вы можете сделать что-то подобное, которое обрабатывает произвольные типы с помощью интерфейса {}. (Я мог бы использовать массив, а не структуру, чтобы сделать его индексируемой, как кортеж, но ключевой идеей является тип интерфейса {}.)

Мой другой ответ показывает, как вы можете сделать что-то подобное, что позволяет избежать создания типа с использованием анонимных структур.

Эти методы имеют некоторые свойства кортежей, но нет, они не являются кортежами.

Ответ 2

Вы можете это сделать. Он выглядит более многословным, чем кортеж, но это большое улучшение, потому что вы получаете проверку типов.

Изменить: Заменен фрагмент с полным рабочим примером, следуя предложению Ника. Ссылка на игровое поле: http://play.golang.org/p/RNx_otTFpk

package main

import "fmt"

func main() {
    queue := make(chan struct {string; int})
    go sendPair(queue)
    pair := <-queue
    fmt.Println(pair.string, pair.int)
}

func sendPair(queue chan struct {string; int}) {
    queue <- struct {string; int}{"http:...", 3}
}

Анонимные структуры и поля отлично подходят для быстрых и грязных решений. Однако для всех, кроме самых простых случаев, вам лучше определить именованную структуру, как и вы.

Ответ 3

Вы можете сделать что-то вроде этого, если хотите

package main

import "fmt"

type Pair struct {
    a, b interface{}
}

func main() {
    p1 := Pair{"finished", 42}
    p2 := Pair{6.1, "hello"}
    fmt.Println("p1=", p1, "p2=", p2)
    fmt.Println("p1.b", p1.b)
    // But to use the values you'll need a type assertion
    s := p1.a.(string) + " now"
    fmt.Println("p1.a", s)
}

Однако я думаю, что вы уже совершенно идиоматичны, и структура прекрасно описывает ваши данные, что является большим преимуществом по сравнению с использованием простых кортежей.