Médio Go
Somando números heterogêneos
Enunciado
Implemente uma função sum(i interface{}) float64 que aceita um int, float64 ou []interface{} contendo números (int ou float64). Retorne a soma de todos os números. Para tipos não suportados, retorne 0 e imprima uma mensagem de aviso. Use type switch, inclusive para o slice.
Requisitos
- Usar type switch para distinguir
int,float64e[]interface{}. - No caso de slice, iterar e somar cada elemento, que também pode ser
intoufloat64. - Retornar
float64com a soma. - Imprimir aviso para tipos não suportados e retornar 0.
Código inicial
package main
import "fmt"
func sum(i interface{}) float64 {
// implemente
return 0
}
func main() {
fmt.Println(sum(10))
fmt.Println(sum(3.14))
fmt.Println(sum([]interface{}{1, 2.5, 3}))
fmt.Println(sum("texto"))
}
Saída esperada
10
3.14
6.5
tipo não suportado: string
0
Ver dica
Dentro do case []interface{}, você pode chamar sum recursivamente para cada elemento, ou fazer um type switch interno. Cuidado com o default para não somar lixo.
Mostrar solução
package main
import "fmt"
// sum soma números de um int, float64 ou slice de interface{}.
func sum(i interface{}) float64 {
switch v := i.(type) {
case int:
return float64(v)
case float64:
return v
case []interface{}:
total := 0.0
for _, elem := range v {
total += sum(elem) // recursão para tratar cada elemento
}
return total
default:
fmt.Printf("tipo não suportado: %T\n", v)
return 0
}
}
func main() {
fmt.Println(sum(10))
fmt.Println(sum(3.14))
fmt.Println(sum([]interface{}{1, 2.5, 3}))
fmt.Println(sum("texto"))
}
Passo a passo
- A função
sumrecebeinterface{}e usa type switch para identificar o tipo dinâmico. - No
case int, convertemos parafloat64e retornamos. - No
case float64, retornamos o próprio valor. - No
case []interface{}, percorremos a slice e chamamossumrecursivamente para cada elemento, acumulando emtotal. - O
defaultimprime uma mensagem com%T(tipo dinâmico) e retorna0. - A recursão permite que slices aninhadas ou elementos de tipos diferentes sejam somados corretamente.
- A função
maintesta cada cenário e imprime o resultado.
Por que funciona
O type switch permite tratar cada tipo de forma específica. A recursão em sum reutiliza a mesma lógica para elementos individuais, mantendo o código conciso. O default garante que tipos inesperados não causem pânico e sejam reportados.
Erros comuns
- Não tratar
intefloat64separadamente: se você tentar fazerv + totalsem converter, o compilador acusa tipos incompatíveis. Sempre converta parafloat64. - Esquecer o
default: se um tipo não suportado for passado, o type switch não faz nada e a função retorna 0 silenciosamente. O aviso ajuda a depurar. - Assumir que
[]inté[]interface{}:[]intnão é[]interface{}. Para aceitar slices de tipos concretos, seria necessário outro case ou reflexão.
Outra forma de resolver
Usar reflexão com reflect.ValueOf(i).Kind() para somar qualquer slice numérico, mas é mais complexo e menos idiomático. O type switch é preferível quando os tipos são conhecidos.
Saída esperada
10
3.14
6.5
tipo não suportado: string
0