Go requiere una conversión explícita entre tipos distintos.
La conversión entre tipos (también conocida como type casting) se realiza mediante una función con el nombre del tipo al que te quieres convertir.
Por ejemplo, para convertir un int en un float64 tendrías que hacer lo siguiente:
var x int = 42 // x has type int
f := float64(x) // f has type float64 (ie. 42.0)
Existe un paquete strconv para convertir entre tipos primitivos (como int) y string.
import "strconv"
var intString string = "42"
var i, err = strconv.Atoi(intString)
var number int = 12
var s string = strconv.Itoa(number)
Las interfaces de Go pueden introducir ambigüedad sobre el tipo subyacente.
Una aserción de tipo nos permite extraer el valor concreto subyacente de un valor de interfaz con esta sintaxis: interfaceVariable.(concreteType).
Por ejemplo:
var input any = 12
number := input.(int)
NOTA: esto provocará un pánico si la variable de interfaz no contiene un valor del tipo concreto.
Podemos comprobar si un valor de interfaz contiene un tipo concreto específico aprovechando los dos valores devueltos de la aserción de tipo: el valor subyacente y un valor booleano que indica si la aserción tuvo éxito. Por ejemplo:
str, ok := input.(string) // no panic if input is not a string
Si input contiene un string, str será el valor subyacente y ok será true.
Si input no contiene un string, str será el valor cero del tipo string (es decir, "", el string vacío) y ok será false.
En ningún caso se produce un pánico.
Un type switch puede realizar varias aserciones de tipo en serie.
Tiene la misma sintaxis que una aserción de tipo (interfaceVariable.(concreteType)), pero concreteType se sustituye por la palabra clave type.
Aquí tienes un ejemplo:
var i any = 12 // try: 12.3, true, int64(12), []int{}, map[string]int{}
switch v := i.(type) {
case int:
fmt.Printf("the integer %d\n", v)
case string:
fmt.Printf("the string %s\n", v)
default:
fmt.Printf("type, %T, not handled explicitly: %#v\n", v, v)
}
Jen trabaja en la sala de clasificación de una gran fábrica. La sala de clasificación necesita procesar todo lo que llega a ella clasificándolo con una etiqueta. Jen se encarga de las cosas que se han clasificado previamente como números y necesita un programa que la ayude con la clasificación.
La mayoría de los valores primitivos deberían recibir etiquetas sencillas.
Para los números, quiere strings que digan "This is the number 2.0" (si el número era 2).
Jen quiere la misma salida para números enteros y números decimales.
Hay unas cuantas interfaces Box que hay que desenvolver para obtener su contenido.
Para una NumberBox, quiere strings que digan "This is a box containing the number 3.0" (si el método Number() devuelve 3).
Para una FancyNumberBox, quiere strings que digan "This is a fancy box containing the number 4.0", pero solo si el tipo es un FancyNumber.
Cualquier cosa inesperada debería devolver "Return to sender" para que Jen pueda devolverlas al lugar de donde vinieron.
Jen quiere que los números devuelvan strings como "This is the number 2.0" (incluyendo un dígito después de la coma decimal):
fmt.Println(DescribeNumber(-12.345))
// Output: This is the number -12.3
Jen quiere que las cajas de números devuelvan strings como "This is a box containing the number 2.0" (de nuevo, incluyendo un dígito después de la coma decimal):
fmt.Println(DescribeNumberBox(numberBoxContaining{12}))
// Output: This is a box containing the number 12.0
Jen necesita una función auxiliar para extraer el número de una FancyNumberBox.
Si la FancyNumberBox es un FancyNumber, extrae su valor y conviértelo de string a int.
Cualquier otro tipo de FancyNumberBox debería devolver 0.
fmt.Println(ExtractFancyNumber(FancyNumber{"10"}))
// Output: 10
fmt.Println(ExtractFancyNumber(AnotherFancyNumber{"4"}))
// Output: 0
Si la FancyNumberBox es un FancyNumber, Jen quiere strings que digan "This is a fancy box containing the number 4.0".
Cualquier otro tipo de FancyNumberBox debería devolver "This is a fancy box containing the number 0.0".
fmt.Println(DescribeFancyNumberBox(FancyNumber{"10"}))
// Output: This is a fancy box containing the number 10.0
fmt.Println(DescribeFancyNumberBox(AnotherFancyNumber{"4"}))
// Output: This is a fancy box containing the number 0.0
NOTA: ¡deberíamos usar la función ExtractFancyNumber!
DescribeAnything, que usa todas las anterioresEsta es la función principal que necesita Jen y que acepta cualquier entrada.
DescribeAnything debería delegar en las otras funciones según el tipo del valor que se le pasa.
Más concretamente:
int como float64 deberían delegar en DescribeNumber
NumberBox debería delegar en DescribeNumberBox
FancyNumberBox debería delegar en DescribeFancyNumberBox
"Return to sender"
fmt.Println(DescribeAnything(numberBoxContaining{12.345}))
// Output: This is a box containing the number 12.3
fmt.Println(DescribeAnything("some string"))
// Output: Return to sender
Regístrate en Exercism para aprender y dominar Go con 34 conceptos166 ejercicios y mentoría humana real, todo gratis.