Tipo di dati coppia / tupla in Go


118

Durante l' esercizio finale del Tour of Go , ho deciso che avevo bisogno di una coda di ( string, int) coppie. È abbastanza facile:

type job struct {
    url string
    depth int
}

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

Ma questo mi ha fatto pensare: ci sono tipi di dati di coppia / tupla incorporati in Go? C'è il supporto per la restituzione di più valori da una funzione, ma AFAICT, le tuple di più valori prodotte non sono cittadini di prima classe nel sistema di tipi di Go. È così?

Per quanto riguarda la parte "cosa hai provato", la sintassi ovvia (dal POV di un programmatore Python)

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

non ha funzionato.

Risposte:


57

Non esiste un tipo di tupla in Go e hai ragione, i valori multipli restituiti dalle funzioni non rappresentano un oggetto di prima classe.

La risposta di Nick mostra come puoi fare qualcosa di simile che gestisce tipi arbitrari usando interface{}. (Potrei aver usato un array piuttosto che una struttura per renderlo indicizzabile come una tupla, ma l'idea chiave è il interface{}tipo)

La mia altra risposta mostra come puoi fare qualcosa di simile che eviti di creare un tipo usando strutture anonime.

Queste tecniche hanno alcune proprietà delle tuple, ma no, non sono tuple.


91

Puoi farlo. Sembra più prolisso di una tupla, ma è un grande miglioramento perché ottieni il controllo del tipo.

Modifica: snippet sostituito con un esempio funzionante completo, seguendo il suggerimento di Nick. Link al parco giochi: 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}
}

Strutture e campi anonimi vanno bene per soluzioni rapide e sporche come questa. Tuttavia, per tutti tranne i casi più semplici, faresti meglio a definire una struttura con nome proprio come hai fatto.


9
Probabilmente dovresti descrivere come ottenere i valori dai membri della struttura anonima perché non penso che sia ovvio per un principiante!
Nick Craig-Wood

9
tuttavia, questo non funzionerà se sono presenti più campi con lo stesso tipo
newacct

1
Puoi avere campi con nome in una struttura anonima, devi solo assicurarti che i campi siano denominati nello stesso modo in cui appare la definizione della struttura anonima (tre volte in questo esempio). I campi anonimi sono più facili se riesci a farla franca .
Sonia

5
Quindi la risposta è "no, non esiste un tipo di tupla"?
Fred Foo

37

Potresti fare qualcosa del genere se lo desideri

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

Tuttavia penso che quello che hai già sia perfettamente idiomatico e la struttura descrive perfettamente i tuoi dati, il che è un grande vantaggio rispetto all'uso di tuple semplici.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.