Percursos
/
Go
Go
/
Exercícios
/
Sala de triagem
Sala de triagem

Sala de triagem

Exercício de aprendizagem

Introdução

Conversão de tipos

O Go exige uma conversão explícita entre tipos diferentes. A conversão entre tipos (também conhecida como conversão de tipos) faz-se através de uma função com o nome do tipo para o qual queremos converter. Por exemplo, para converter um int num float64, tens de fazer o seguinte:

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

Conversão entre tipos primitivos e strings

Existe um pacote strconv para converter entre tipos primitivos (como 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)

Asserções de tipo

As interfaces em Go podem introduzir ambiguidade quanto ao tipo subjacente. Uma asserção de tipo permite-nos extrair o valor concreto subjacente de um valor de interface, usando esta sintaxe: interfaceVariable.(concreteType).

Por exemplo:

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

NOTA: isto provoca um panic se a variável de interface não contiver um valor do tipo concreto.

Podemos testar se um valor de interface contém um tipo concreto específico, recorrendo aos dois valores devolvidos pela asserção de tipo: o valor subjacente e um valor do tipo Boolean que indica se a asserção foi bem-sucedida. Por exemplo:

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

Se input contiver uma string, então str será o valor subjacente e ok será true. Se input não contiver uma string, então str será o valor zero do tipo string (ou seja, "", a string vazia) e ok será false. Não ocorre um panic em nenhum dos casos.

Switches de tipo

Um switch de tipo pode realizar várias asserções de tipo em série. Tem a mesma sintaxe que uma asserção de tipo (interfaceVariable.(concreteType)), mas o concreteType é substituído pela palavra-chave type. Eis um exemplo:

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

Instruções

A Jen trabalha na sala de triagem de uma grande fábrica. A sala de triagem tem de processar tudo o que lá entra, categorizando-o com uma etiqueta. A Jen é responsável pelos itens pré-categorizados como números e precisa de um programa que a ajude com a triagem.

A maioria dos valores primitivos deve receber etiquetas diretas. Para os números, quer strings que digam "This is the number 2.0" (se o número for 2). A Jen quer o mesmo resultado para inteiros e para números de vírgula flutuante.

Há algumas interfaces Box que é preciso desembrulhar para obter o seu conteúdo. Para uma NumberBox, quer strings que digam "This is a box containing the number 3.0" (se o método Number() devolver 3). Para uma FancyNumberBox, quer strings que digam "This is a fancy box containing the number 4.0", mas apenas se o tipo for um FancyNumber.

Tudo o que for inesperado deve dizer "Return to sender", para que a Jen os possa devolver à origem.

1. Descrever números simples

A Jen quer que os números devolvam strings como "This is the number 2.0" (incluindo um algarismo depois da vírgula):

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

2. Descrever uma caixa de números

A Jen quer que as caixas de números devolvam strings como "This is a box containing the number 2.0" (mais uma vez, incluindo um algarismo depois da vírgula):

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

3. Implementar um método que extrai o número de uma caixa de números sofisticada

A Jen precisa de uma função auxiliar para extrair o número de uma FancyNumberBox. Se a FancyNumberBox for um FancyNumber, extrai o seu valor e converte-o de uma string para um int. Qualquer outro tipo de FancyNumberBox deve devolver 0.

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

4. Descrever uma caixa de números sofisticada

Se a FancyNumberBox for um FancyNumber, a Jen quer strings que digam "This is a fancy box containing the number 4.0". Qualquer outro tipo de FancyNumberBox deve dizer "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: devemos usar a função ExtractFancyNumber!

5. Implementar DescribeAnything, que usa todas as anteriores

Esta é a função principal de que a Jen precisa, que recebe qualquer valor de entrada. A DescribeAnything deve delegar nas outras funções com base no tipo do valor recebido. Mais concretamente:

  • int e float64 devem ambos delegar em DescribeNumber
  • NumberBox deve delegar em DescribeNumberBox
  • FancyNumberBox deve delegar em DescribeFancyNumberBox
  • qualquer outra coisa deve resultar em "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 via GitHub A ligação abre numa nova janela ou separador
Go Exercism

Estás pronto para começar Sala de triagem?

Inscreve-te no Exercism para aprenderes e dominares Go com 34 conceitos166 exercícios, e mentoria humana real, tudo grátis.