---
title: "cannot range over em Go"
url: "https://golang.com.br/erros/cannot-range-over/"
markdown_url: "https://golang.com.br/erros/cannot-range-over.MD"
description: "Resolva o erro 'cannot range over' em Go. Entenda quais tipos suportam range, como iterar corretamente e use iteradores customizados no Go."
date: "2026-05-12"
author: "Golang Brasil"
---

# cannot range over em Go

Resolva o erro 'cannot range over' em Go. Entenda quais tipos suportam range, como iterar corretamente e use iteradores customizados no Go.


# cannot range over em Go

O erro **"cannot range over X"** aparece quando você tenta usar `for range` com um tipo que não suporta iteração. O `range` do Go funciona apenas com tipos específicos, e usá-lo com qualquer outro tipo resulta em erro de compilação.

---

## A Mensagem de Erro

```
./main.go:10:15: cannot range over num (variable of type int)
./main.go:12:15: cannot range over usuario (variable of type Usuario)
```

---

## Tipos que Suportam range

Em Go, `range` funciona apenas com estes tipos:

| Tipo | Produz | Exemplo |
|------|--------|---------|
| `array` / `slice` | índice, valor | `for i, v := range []int{1,2,3}` |
| `string` | índice, rune | `for i, r := range "Go"` |
| `map` | chave, valor | `for k, v := range map[string]int{}` |
| `channel` | valor | `for v := range ch` |
| `int` (Go 1.22+) | índice | `for i := range 5` |
| `func(yield)` (Go 1.23+) | valores do yield | `for v := range iterador` |

---

## Causas Comuns

### 1. Range sobre Tipo Numérico (antes do Go 1.22)

Antes do [Go 1.22](/blog/go-1-22/), não era possível usar `range` com inteiros:

```go
package main

import "fmt"

func main() {
    // ERRO (antes do Go 1.22): cannot range over 5 (untyped int constant)
    for i := range 5 {
        fmt.Println(i)
    }
}
```

### 2. Range sobre Struct

Structs não são iteráveis por padrão:

```go
package main

import "fmt"

type Ponto struct {
    X, Y int
}

func main() {
    p := Ponto{X: 10, Y: 20}

    // ERRO: cannot range over p (variable of type Ponto)
    for v := range p {
        fmt.Println(v)
    }
}
```

### 3. Range sobre Ponteiro para Slice

Um ponteiro para slice não é um slice:

```go
package main

import "fmt"

func main() {
    nums := &[]int{1, 2, 3}

    // ERRO: cannot range over nums (variable of type *[]int)
    for _, v := range nums {
        fmt.Println(v)
    }
}
```

### 4. Range sobre Interface Sem Tipo Concreto

Se uma interface pode ser qualquer tipo, o compilador não sabe como iterar:

```go
package main

import "fmt"

func processar(dados interface{}) {
    // ERRO: cannot range over dados (variable of type interface{})
    for _, v := range dados {
        fmt.Println(v)
    }
}
```

---

## Como Resolver

### Solução 1: Range sobre Inteiro (Go 1.22+)

A partir do [Go 1.22](/blog/go-1-22/), `range` funciona com inteiros:

```go
package main

import "fmt"

func main() {
    // Go 1.22+: range sobre inteiro
    for i := range 5 {
        fmt.Println(i) // 0, 1, 2, 3, 4
    }
}
```

Se estiver em uma versão anterior, use o loop `for` tradicional:

```go
for i := 0; i < 5; i++ {
    fmt.Println(i)
}
```

### Solução 2: Converter Struct para Slice

Para iterar sobre campos de uma struct, converta explicitamente:

```go
package main

import "fmt"

type Ponto struct {
    X, Y, Z int
}

func (p Ponto) Coords() []int {
    return []int{p.X, p.Y, p.Z}
}

func main() {
    p := Ponto{X: 10, Y: 20, Z: 30}

    for i, v := range p.Coords() {
        fmt.Printf("coord[%d] = %d\n", i, v)
    }
}
```

### Solução 3: Desreferenciar o Ponteiro

Para ponteiros para slices, desreferencie com `*`:

```go
package main

import "fmt"

func main() {
    nums := &[]int{1, 2, 3}

    // Desreferencia o ponteiro
    for _, v := range *nums {
        fmt.Println(v)
    }
}
```

### Solução 4: Type Assertion para Interfaces

Converta a interface para o tipo concreto:

```go
package main

import "fmt"

func processar(dados interface{}) {
    // Type assertion para slice
    if slice, ok := dados.([]int); ok {
        for _, v := range slice {
            fmt.Println(v)
        }
        return
    }

    // Type switch para múltiplos tipos
    switch d := dados.(type) {
    case []string:
        for _, v := range d {
            fmt.Println(v)
        }
    case map[string]int:
        for k, v := range d {
            fmt.Printf("%s: %d\n", k, v)
        }
    default:
        fmt.Println("tipo não suportado para iteração")
    }
}

func main() {
    processar([]int{1, 2, 3})
    processar([]string{"a", "b", "c"})
}
```

### Solução 5: Iteradores Customizados (Go 1.23+)

A partir do [Go 1.23](/blog/go-1-23/), você pode definir iteradores customizados usando `range over func`. Isso é o que a comunidade chama de [iteradores em Go](/blog/iteradores-go-range-over-func/):

```go
package main

import (
    "fmt"
    "iter"
)

type Arvore struct {
    Valor    int
    Esquerda *Arvore
    Direita  *Arvore
}

// Iterador in-order para árvore binária
func (a *Arvore) InOrder() iter.Seq[int] {
    return func(yield func(int) bool) {
        if a == nil {
            return
        }
        for v := range a.Esquerda.InOrder() {
            if !yield(v) {
                return
            }
        }
        if !yield(a.Valor) {
            return
        }
        for v := range a.Direita.InOrder() {
            if !yield(v) {
                return
            }
        }
    }
}

func main() {
    arvore := &Arvore{
        Valor: 2,
        Esquerda: &Arvore{Valor: 1},
        Direita:  &Arvore{Valor: 3},
    }

    // Usa range com iterador customizado
    for v := range arvore.InOrder() {
        fmt.Println(v) // 1, 2, 3
    }
}
```

### Solução 6: Usar Generics para Iteração

Com [generics](/blog/go-1-18/), crie funções de iteração reutilizáveis:

```go
package main

import "fmt"

func Filtrar[T any](items []T, pred func(T) bool) []T {
    var resultado []T
    for _, item := range items {
        if pred(item) {
            resultado = append(resultado, item)
        }
    }
    return resultado
}

func main() {
    nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

    pares := Filtrar(nums, func(n int) bool {
        return n%2 == 0
    })

    for _, v := range pares {
        fmt.Println(v) // 2, 4, 6, 8, 10
    }
}
```

---

## Dicas para Evitar Este Erro

1. **Conheça os tipos iteráveis** — slices, arrays, maps, strings, channels e (Go 1.22+) inteiros.

2. **Atualize para Go 1.22+** — `range` sobre inteiros simplifica muitos loops. Veja [como instalar Go](/aprenda/primeiros-passos/).

3. **Explore iteradores** — o [Go 1.23](/blog/go-1-23/) introduziu `range over func`, revolucionando a iteração customizada. Leia sobre [iteradores em Go](/blog/iteradores-go-range-over-func/).

4. **Prefira slices a ponteiros de slices** — passar slices por valor já é eficiente (slices são referências internas).

5. **Use generics** — para funções genéricas de iteração. Veja [generics no Go 1.18](/blog/go-1-18/).

---

## Erros Relacionados

- [declared and not used](/erros/declared-not-used/) — variáveis de range não usadas
- [cannot use X as type Y](/erros/cannot-use-x-as-type-y/) — problemas de tipo ao iterar
- [Iteradores em Go](/blog/iteradores-go-range-over-func/) — range over func no Go 1.23
- [Go para Iniciantes](/aprenda/go-para-iniciantes/) — fundamentos de loops e iteração
