cannot use X as type Y em Go

O erro “cannot use X (variable of type A) as type B” é uma das mensagens mais frequentes que desenvolvedores Go encontram. Ele aparece quando você tenta usar um valor de um tipo onde o compilador espera outro tipo incompatível.

Go é uma linguagem com tipagem estática forte, o que significa que o compilador verifica todos os tipos em tempo de compilação. Diferente de linguagens como Python ou JavaScript, Go não faz conversões implícitas entre tipos — e isso é uma escolha deliberada de design.


A Mensagem de Erro

O compilador exibe variações desta mensagem:

cannot use x (variable of type int) as type float64 in argument to math.Sqrt
cannot use s (variable of type string) as type int in assignment
cannot use myStruct (variable of type *MyStruct) as type MyInterface in argument to process

Causas Comuns

1. Tipos Numéricos Diferentes

Em Go, int, int32, int64, float32 e float64 são tipos distintos. Não há conversão implícita entre eles:

package main

import "fmt"

func main() {
    var idade int = 30
    var peso float64 = 75.5

    // ERRO: cannot use idade (variable of type int) as type float64
    total := peso + idade
    fmt.Println(total)
}

2. Tipos Definidos pelo Usuário

Mesmo que dois tipos tenham a mesma estrutura subjacente, Go os trata como tipos distintos:

package main

import "fmt"

type Celsius float64
type Fahrenheit float64

func mostrarCelsius(c Celsius) {
    fmt.Printf("%.1f°C\n", c)
}

func main() {
    var temp Fahrenheit = 98.6
    // ERRO: cannot use temp (variable of type Fahrenheit) as type Celsius
    mostrarCelsius(temp)
}

3. Interface Não Satisfeita

Quando um tipo não implementa todos os métodos de uma interface:

package main

import "fmt"

type Stringer interface {
    String() string
}

type Produto struct {
    Nome  string
    Preco float64
}

// Produto não implementa String() — falta o método!

func imprimir(s Stringer) {
    fmt.Println(s.String())
}

func main() {
    p := Produto{Nome: "Teclado", Preco: 199.90}
    // ERRO: cannot use p (variable of type Produto) as type Stringer
    imprimir(p)
}

4. Ponteiro vs Valor

Métodos definidos com receiver de ponteiro não satisfazem a interface quando você passa um valor:

package main

import "fmt"

type Writer interface {
    Write(data []byte) (int, error)
}

type Logger struct{}

// Método com receiver de ponteiro
func (l *Logger) Write(data []byte) (int, error) {
    fmt.Println(string(data))
    return len(data), nil
}

func process(w Writer) {
    w.Write([]byte("log"))
}

func main() {
    logger := Logger{}
    // ERRO: cannot use logger (variable of type Logger) as type Writer
    // Logger does not implement Writer (Write method has pointer receiver)
    process(logger)
}

Como Resolver

Solução 1: Conversão Explícita de Tipos

Para tipos numéricos e tipos com mesma estrutura subjacente, use conversão explícita:

package main

import (
    "fmt"
    "math"
)

func main() {
    var idade int = 30
    var peso float64 = 75.5

    // Converte int para float64 explicitamente
    total := peso + float64(idade)
    fmt.Println(total) // 105.5

    // Conversão para usar com math.Sqrt
    resultado := math.Sqrt(float64(idade))
    fmt.Printf("%.2f\n", resultado)
}

Solução 2: Implementar a Interface

Adicione os métodos necessários ao seu tipo:

package main

import "fmt"

type Stringer interface {
    String() string
}

type Produto struct {
    Nome  string
    Preco float64
}

// Agora Produto implementa Stringer
func (p Produto) String() string {
    return fmt.Sprintf("%s (R$ %.2f)", p.Nome, p.Preco)
}

func imprimir(s Stringer) {
    fmt.Println(s.String())
}

func main() {
    p := Produto{Nome: "Teclado", Preco: 199.90}
    imprimir(p) // Teclado (R$ 199.90)
}

Solução 3: Usar Ponteiro Quando Necessário

Quando os métodos usam receiver de ponteiro, passe um ponteiro:

func main() {
    logger := &Logger{} // Ponteiro para Logger
    process(logger)     // Agora funciona!
}

Solução 4: Type Assertion para Interfaces

Quando trabalha com interface{} ou any, use type assertion:

package main

import "fmt"

func processar(valor any) {
    // Type assertion segura
    if texto, ok := valor.(string); ok {
        fmt.Println("É string:", texto)
    } else if numero, ok := valor.(int); ok {
        fmt.Println("É int:", numero)
    }
}

func main() {
    processar("hello")
    processar(42)
}

Dicas para Evitar Este Erro

  1. Defina tipos consistentes desde o início — ao projetar suas structs e funções, escolha tipos uniformes (por exemplo, sempre int64 para IDs).

  2. Use any com cautela — o tipo any (alias para interface{}) remove a verificação de tipos. Prefira generics quando possível.

  3. Confira o receiver dos métodos — se uma interface exige um método, verifique se ele é definido com receiver de valor ou ponteiro. Veja mais sobre isso em interfaces em Go.

  4. Leia a mensagem completa — o compilador do Go é preciso. A mensagem diz exatamente qual tipo é esperado e qual foi fornecido.

  5. Use seu editor — ferramentas como o gopls (integrado ao VS Code e outros editores) destacam este erro em tempo real.


Erros Relacionados