Desafio Go

Processador de comandos com type switch

Enunciado

Crie um sistema que processa comandos representados por interface{}. Os comandos possíveis são:

  • string: imprime "Executando: <comando>".
  • int: imprime "Código: <número>".
  • []string: executa cada string como comando.
  • nil: imprime "Comando vazio".
  • bool ou float64: imprime "Comando inválido: <valor>".
  • Qualquer outro tipo: imprime "Tipo desconhecido: <tipo>".

Implemente process(cmd interface{}) usando type switch, incluindo casos múltiplos para bool e float64. Demonstre com exemplos, incluindo um slice de strings e um nil.

Requisitos

  • Usar type switch com case bool, float64: (casos múltiplos).
  • Tratar case nil separadamente.
  • Para []string, iterar e processar cada string recursivamente.
  • Imprimir mensagens exatas conforme especificado.

Código inicial

package main

import "fmt"

func process(cmd interface{}) {
	// implemente
}

func main() {
	process("iniciar")
	process(404)
	process([]string{"a", "b"})
	process(nil)
	process(true)
	process(3.14)
	process([]int{1, 2})
}

Saída esperada

Executando: iniciar
Código: 404
Executando: a
Executando: b
Comando vazio
Comando inválido: true
Comando inválido: 3.14
Tipo desconhecido: []int
Ver dica

No case []string, itere e chame process para cada string. No case bool, float64, a variável v terá tipo interface{}; use %v para imprimir o valor.

Mostrar solução
package main

import "fmt"

// process executa um comando de acordo com seu tipo dinâmico.
func process(cmd interface{}) {
	switch v := cmd.(type) {
	case nil:
		fmt.Println("Comando vazio")
	case string:
		fmt.Printf("Executando: %s\n", v)
	case int:
		fmt.Printf("Código: %d\n", v)
	case []string:
		for _, s := range v {
			process(s) // processa cada string como comando
		}
	case bool, float64:
		// v tem tipo interface{} aqui, pois são múltiplos tipos
		fmt.Printf("Comando inválido: %v\n", v)
	default:
		fmt.Printf("Tipo desconhecido: %T\n", v)
	}
}

func main() {
	process("iniciar")
	process(404)
	process([]string{"a", "b"})
	process(nil)
	process(true)
	process(3.14)
	process([]int{1, 2})
}

Passo a passo

  1. A função process recebe interface{} e usa type switch para ramificar.
  2. case nil trata interface nula, imprimindo "Comando vazio".
  3. case string imprime o comando formatado.
  4. case int imprime o código.
  5. case []string itera sobre a slice e chama process recursivamente para cada string, reutilizando a lógica de string.
  6. case bool, float64 agrupa dois tipos. Como são múltiplos, a variável v tem tipo interface{}, então usamos %v para imprimir o valor.
  7. default captura tipos não previstos, como []int, e imprime o tipo com %T.
  8. main demonstra cada caso, incluindo um slice de strings e um nil.

Por que funciona

O type switch com casos múltiplos permite tratar bool e float64 da mesma forma sem duplicar código. A recursão no case []string reaproveita o tratamento de strings, mantendo a consistência. O case nil é essencial para capturar interfaces nulas, que de outra forma cairiam no default.

Erros comuns

  • Tentar acessar v como bool no case bool, float64: como são múltiplos tipos, v é interface{}. Fazer v == true causa erro de compilação. Use %v ou faça uma asserção dentro do case.
  • Esquecer o case nil: nil cairia no default e imprimiria "Tipo desconhecido: <nil>", o que não é o desejado.
  • Confundir []string com []interface{}: são tipos diferentes. []string é tratado no case específico; []interface{} cairia no default.
  • Recursão infinita: se um []string contivesse a si mesmo (impossível em Go), mas em geral, certifique-se de que a recursão sempre avança para um caso base.

Outra forma de resolver

Poderia-se usar uma interface Command com método Execute(), mas isso exigiria definir tipos concretos. O type switch é mais direto para dados dinâmicos.

Saída esperada

Executando: iniciar
Código: 404
Executando: a
Executando: b
Comando vazio
Comando inválido: true
Comando inválido: 3.14
Tipo desconhecido: []int