go - Tipo de datos de par/tupla en Ir
tuples pair (3)
Mientras hacía el ejercicio final del Tour of Go , decidí que necesitaba una cola de pares ( string
, int
). Eso es bastante fácil:
type job struct {
url string
depth int
}
queue := make(chan job)
queue <- job{url, depth}
Pero esto me hizo pensar: ¿hay tipos de datos incorporados de par / tupla en Go? Existe soporte para devolver múltiples valores de una función, pero AFAICT, las tuplas de múltiples valores producidos no son ciudadanos de primera clase en el sistema de tipos de Go. Es ese el caso?
En cuanto a la parte "¿qué has probado?", La sintaxis obvia (del punto de vista de un programador de Python)
queue := make(chan (string, int))
no funcionó
No hay ningún tipo de tupla en Go, y está en lo cierto, los múltiples valores devueltos por las funciones no representan un objeto de primera clase.
La respuesta de Nick muestra cómo puedes hacer algo similar que maneja tipos arbitrarios usando la interface{}
. (Podría haber usado una matriz en lugar de una estructura para hacerlo indexable como una tupla, pero la idea clave es la interface{}
tipo)
Mi otra respuesta muestra cómo puedes hacer algo similar que evita crear un tipo usando estructuras anónimas.
Estas técnicas tienen algunas propiedades de tuplas, pero no, no son tuplas.
Podrías hacer algo como esto si quisieras
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)
}
Sin embargo, creo que lo que tienes es perfectamente idiomático y la estructura describe perfectamente tus datos, lo que es una gran ventaja sobre el uso de tuplas simples.
Puedes hacerlo. Parece más prolijo que una tupla, pero es una gran mejora porque obtienes la verificación de tipo.
Editar: fragmento reemplazado con un ejemplo de trabajo completo, siguiendo la sugerencia de Nick. Enlace de Playground: 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}
}
Las estructuras y campos anónimos están bien para soluciones rápidas y sucias como esta. Sin embargo, para todos los casos menos simples, sería mejor definir una estructura con nombre tal como lo hizo.