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


при этом заключительное упражнение тура Go, я решил, что мне нужна очередь (string,int) пар. Это достаточно просто:

type job struct {
    url string
    depth int
}

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

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

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

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

не работает.

3 66

3 ответа:

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

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

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

эти методы имеют некоторые свойства туплю, но нет, они не кортежи.

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

Edit: заменен фрагмент с полным рабочим примером, следуя предложению Ника. Игровая площадка Ссылка: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}
}

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

вы могли бы сделать что-то подобное, если бы вы хотели

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

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