Track
/
Go
Go
/
Esercizi
/
Sala di smistamento
Sala di smistamento

Sala di smistamento

Esercizio di apprendimento

Introduzione

Conversione di tipo

Go richiede una conversione esplicita tra tipi diversi. La conversione tra tipi (nota anche come type casting) avviene tramite una funzione con il nome del tipo in cui convertire. Ad esempio, per convertire un int in un float64 devi fare quanto segue:

var x int = 42 // x has type int
f := float64(x) // f has type float64 (ie. 42.0)

Convertire tra tipi primitivi e stringhe

Esiste un pacchetto strconv per convertire tra tipi primitivi (come int) e string.

import "strconv"

var intString string = "42"
var i, err = strconv.Atoi(intString)

var number int = 12
var s string = strconv.Itoa(number)

Asserzioni di tipo

Le interfacce in Go possono introdurre ambiguità sul tipo sottostante. Un'asserzione di tipo permette di estrarre il valore concreto sottostante di un valore di interfaccia usando questa sintassi: interfaceVariable.(concreteType).

Ad esempio:

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

NOTA: questo causerà un panic se la variabile di interfaccia non contiene un valore del tipo concreto.

Possiamo verificare se un valore di interfaccia contiene un tipo concreto specifico sfruttando entrambi i valori restituiti dall'asserzione di tipo: il valore sottostante e un valore booleano che indica se l'asserzione è riuscita. Ad esempio:

str, ok := input.(string) // no panic if input is not a string

Se input contiene una string, allora str sarà il valore sottostante e ok sarà true. Se input non contiene una string, allora str sarà il valore zero del tipo string (cioè "", la stringa vuota) e ok sarà false. In nessun caso si verifica un panic.

Switch di tipo

Uno switch di tipo può eseguire diverse asserzioni di tipo in serie. Ha la stessa sintassi di un'asserzione di tipo (interfaceVariable.(concreteType)), ma concreteType viene sostituito con la parola chiave type. Ecco un esempio:

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

Istruzioni

Jen lavora nella stanza di smistamento di una grande fabbrica. La stanza di smistamento deve elaborare tutto ciò che vi entra categorizzandolo con un'etichetta. Jen è responsabile delle cose che sono state pre-categorizzate come numeri e ha bisogno di un programma che la aiuti con lo smistamento.

La maggior parte dei valori primitivi dovrebbe ricevere etichette semplici. Per i numeri, vuole stringhe che dicano "This is the number 2.0" (se il numero era 2). Jen vuole lo stesso output per interi e numeri in virgola mobile.

Ci sono alcune interfacce Box che vanno scartate per ottenerne il contenuto. Per un NumberBox, vuole stringhe che dicano "This is a box containing the number 3.0" (se il metodo Number() restituisce 3). Per un FancyNumberBox, vuole stringhe che dicano "This is a fancy box containing the number 4.0", ma solo se il tipo è un FancyNumber.

Qualsiasi cosa inaspettata dovrebbe dire "Return to sender", così Jen può rispedirla da dove è venuta.

1. Descrivi i numeri semplici

Jen vuole che i numeri restituiscano stringhe come "This is the number 2.0" (inclusa una cifra dopo il punto decimale):

fmt.Println(DescribeNumber(-12.345))
// Output: This is the number -12.3

2. Descrivi una scatola di numeri

Jen vuole che le scatole di numeri restituiscano stringhe come "This is a box containing the number 2.0" (di nuovo, inclusa una cifra dopo il punto decimale):

fmt.Println(DescribeNumberBox(numberBoxContaining{12}))
// Output: This is a box containing the number 12.0

3. Implementa un metodo che estrae il numero da una scatola di numeri fancy

Jen ha bisogno di una funzione ausiliaria per estrarre il numero da un FancyNumberBox. Se il FancyNumberBox è un FancyNumber, estrai il suo valore e convertilo da string a int. Qualsiasi altro tipo di FancyNumberBox dovrebbe restituire 0.

fmt.Println(ExtractFancyNumber(FancyNumber{"10"}))
// Output: 10
fmt.Println(ExtractFancyNumber(AnotherFancyNumber{"4"}))
// Output: 0

4. Descrivi una scatola di numeri fancy

Se il FancyNumberBox è un FancyNumber, Jen vuole stringhe che dicano "This is a fancy box containing the number 4.0". Qualsiasi altro tipo di FancyNumberBox dovrebbe dire "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: dobbiamo usare la funzione ExtractFancyNumber!

5. Implementa DescribeAnything che le usa tutte

Questa è la funzione principale di cui Jen ha bisogno, che accetta qualsiasi input. DescribeAnything dovrebbe delegare alle altre funzioni in base al tipo del valore passato. Più precisamente:

  • int e float64 dovrebbero entrambi delegare a DescribeNumber
  • NumberBox dovrebbe delegare a DescribeNumberBox
  • FancyNumberBox dovrebbe delegare a DescribeFancyNumberBox
  • qualsiasi altra cosa dovrebbe dare come risultato "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
Modifica tramite GitHub Il link si apre in una nuova finestra o scheda
Go Exercism

Vuoi iniziare Sala di smistamento?

Iscriviti a Exercism per imparare e padroneggiare Go con 34 concetti166 esercizi e il mentoring di persone reali, tutto gratis.