Rutas
/
Go
Go
/
Ejercicios
/
Sala de clasificación
Sala de clasificación

Sala de clasificación

Ejercicio de aprendizaje

Introducción

Conversión de tipos

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)

Conversión entre tipos primitivos y strings

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)

Aserciones de tipo

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.

Type switches

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

Instrucciones

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.

1. Describe números sencillos

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

2. Describe una caja de números

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

3. Implementa un método que extraiga el número de una caja de números elegante

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

4. Describe una caja de números elegante

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!

5. Implementa DescribeAnything, que usa todas las anteriores

Esta 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:

  • tanto int como float64 deberían delegar en DescribeNumber
  • NumberBox debería delegar en DescribeNumberBox
  • FancyNumberBox debería delegar en DescribeFancyNumberBox
  • cualquier otra cosa debería dar como resultado "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
Editar en GitHub El enlace se abre en una ventana o pestaña nueva
Go Exercism

¿Listo para empezar Sala de clasificación?

Regístrate en Exercism para aprender y dominar Go con 34 conceptos166 ejercicios y mentoría humana real, todo gratis.