Tracks
/
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 diferentes. La conversión entre tipos (también conocida como casting) se hace mediante una función con el nombre del tipo al que quieres convertir. Por ejemplo, para convertir un int a 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 en Go pueden introducir ambigüedad sobre el tipo subyacente. Una aserción de tipo nos permite extraer el valor concreto subyacente del valor de la interfaz usando esta sintaxis: interfaceVariable.(concreteType).

Por ejemplo:

var input any = 12
number := input.(int)

NOTA: esto provocará un panic 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 usando los dos valores de retorno de la aserción de tipo: el valor subyacente y un valor Boolean 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, entonces str será el valor subyacente y ok será true. Si input no contiene un string, entonces str será el valor cero del tipo string (es decir, "", el string vacío) y ok será false. En ningún caso ocurre un panic.

Type switch

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 reemplaza 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 fábrica grande. La sala de clasificación necesita procesar todo lo que llega categorizándolo con una etiqueta. Jen se encarga de las cosas que se clasificaron previamente como números y necesita un programa que la ayude con la clasificación.

La mayoría de los valores primitivos debería 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 el mismo resultado para enteros y números de punto flotante.

Hay unas cuantas interfaces Box que hay que desenvolver para obtener su contenido. Para un NumberBox, quiere strings que digan "This is a box containing the number 3.0" (si el método Number() devuelve 3). Para un 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 debe decir "Return to sender" para que Jen pueda devolverlas de donde vinieron.

1. Describe números simples

Jen quiere que los números devuelvan strings como "This is the number 2.0" (incluyendo un dígito después del punto 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" (una vez más, incluyendo un dígito después del punto 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 un FancyNumberBox. Si el FancyNumberBox es un FancyNumber, extrae su valor y conviértelo de string a int. Cualquier otro tipo de FancyNumberBox debe 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 el FancyNumberBox es un FancyNumber, Jen quiere strings que digan "This is a fancy box containing the number 4.0". Cualquier otro tipo de FancyNumberBox debe decir "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 ellas

Esta es la función principal que Jen necesita y que recibe cualquier argumento. DescribeAnything debe delegar a las otras funciones según el tipo del valor que se le pase. Más específicamente:

  • Tanto int como float64 deben delegar a DescribeNumber
  • NumberBox debe delegar a DescribeNumberBox
  • FancyNumberBox debe delegar a DescribeFancyNumberBox
  • cualquier otra cosa debe 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 una pestaña nuevas
Go Exercism

¿Todo 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.