En faisant les exercice final du Tour of Go , j'ai décidé qu'il me fallait une file d'attente de (string
, int
). C'est assez facile:
type job struct {
url string
depth int
}
queue := make(chan job)
queue <- job{url, depth}
Mais cela m’a amené à penser: existe-t-il des types de données paire/Tuple intégrés dans Go? Il existe un support pour renvoyant plusieurs valeurs à partir d'une fonction, mais AFAICT, les multiniveaux de valeurs générés ne sont pas des citoyens de première classe dans le système de types de Go. Est-ce le cas?
En ce qui concerne la partie "qu’avez-vous essayé", la syntaxe évidente (à partir de Python)
queue := make(chan (string, int))
n'a pas fonctionné.
Il n'y a pas de type de tuples dans Go, et vous avez raison, les multiples valeurs renvoyées par les fonctions ne représentent pas un objet de première classe.
La réponse de Nick montre comment vous pouvez faire quelque chose de similaire qui traite des types arbitraires en utilisant interface{}
. (J'aurais peut-être utilisé un tableau plutôt qu'une structure pour le rendre indexable comme un tuple, mais l'idée clé est le interface{}
type)
Mon autre réponse montre comment vous pouvez faire quelque chose de similaire qui évite de créer un type en utilisant des structures anonymes.
Ces techniques ont certaines propriétés des n-uplets, mais non, ce ne sont pas des n-uplets.
Tu peux le faire. Cela semble plus verbeux qu'un tuple, mais c'est une grande amélioration parce que vous obtenez une vérification de type.
Édition: extrait remplacé par un exemple de travail complet, selon la suggestion de Nick. Lien du terrain de jeu: 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}
}
Les structures et champs anonymes conviennent aux solutions rapides et sales comme celle-ci. Cependant, dans tous les cas sauf les plus simples, vous feriez mieux de définir une structure nommée comme vous le faisiez.
Tu pourrais faire quelque chose comme ça si tu voulais
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)
}
Cependant, je pense que ce que vous avez déjà est parfaitement idiomatique et que la structure décrit parfaitement vos données, ce qui constitue un gros avantage par rapport à l'utilisation de simples nuplets.