---
title: "Ranges em Rust: .., ..=, e RangeFull"
url: "https://rustlang.com.br/stdlib/ranges/"
markdown_url: "https://rustlang.com.br/stdlib/ranges.MD"
description: "Guia completo de ranges em Rust: Range, RangeInclusive, RangeFrom, RangeTo, RangeFull, iteração, slicing, contains e uso em for loops. Exemplos práticos."
date: "2026-02-23"
author: "Equipe Rust Brasil"
---

# Ranges em Rust: .., ..=, e RangeFull

Guia completo de ranges em Rust: Range, RangeInclusive, RangeFrom, RangeTo, RangeFull, iteração, slicing, contains e uso em for loops. Exemplos práticos.


Os **ranges** (faixas) em Rust são tipos que representam intervalos de valores. Eles são usados extensivamente em **for loops**, **fatiamento de slices**, **verificação de pertinência** e **consultas em coleções ordenadas**. A sintaxe com `..` e `..=` é compacta e expressiva, sendo um dos recursos mais utilizados da linguagem.

## Tipos de Range

Rust possui seis tipos de range, todos no módulo `std::ops`:

| Sintaxe | Tipo | Intervalo Matemático | Exemplo |
|---|---|---|---|
| `a..b` | `Range<T>` | [a, b) | `0..10` = 0 a 9 |
| `a..=b` | `RangeInclusive<T>` | [a, b] | `0..=10` = 0 a 10 |
| `a..` | `RangeFrom<T>` | [a, +inf) | `5..` = 5, 6, 7, ... |
| `..b` | `RangeTo<T>` | (-inf, b) | `..5` = até 4 |
| `..=b` | `RangeToInclusive<T>` | (-inf, b] | `..=5` = até 5 |
| `..` | `RangeFull` | (-inf, +inf) | `..` = tudo |

## Criando e Usando Ranges

```rust
use std::ops::{Range, RangeInclusive, RangeFrom, RangeTo, RangeFull};

fn main() {
    // Range exclusivo: [0, 5)
    let r1: Range<i32> = 0..5;
    println!("0..5 = {:?}", r1);

    // Range inclusivo: [0, 5]
    let r2: RangeInclusive<i32> = 0..=5;
    println!("0..=5 = {:?}", r2);

    // Range aberto à direita: [3, +inf)
    let r3: RangeFrom<i32> = 3..;
    println!("3.. = {:?}", r3);

    // Range aberto à esquerda: (-inf, 5)
    let r4: RangeTo<i32> = ..5;
    println!("..5 = {:?}", r4);

    // Range full (todos os elementos)
    let r5: RangeFull = ..;

    // Ranges com outros tipos
    let letras = 'a'..='z';
    let floats = 0.0..1.0;

    println!("Letras: {:?}", letras);
    println!("Floats: {:?}", floats);
}
```

## Tabela de Operações

| Operação | Funciona Com | Descrição |
|---|---|---|
| `for x in range` | `Range`, `RangeInclusive`, `RangeFrom` | Iteração |
| `slice[range]` | Todos os tipos | Fatiamento |
| `range.contains(&v)` | Todos os tipos | Verificação de pertinência |
| `range.is_empty()` | `Range`, `RangeInclusive` | Verifica se o intervalo é vazio |
| `range.count()` | `Range`, `RangeInclusive` | Número de elementos (consome) |
| `range.sum()` | `Range`, `RangeInclusive` | Soma dos elementos (consome) |
| `range.collect()` | `Range`, `RangeInclusive` | Coleta em coleção |
| `range.rev()` | `Range`, `RangeInclusive` | Iteração reversa |
| `range.step_by(n)` | `Range`, `RangeInclusive` | Passo customizado |
| `range.zip(other)` | `Range`, `RangeInclusive` | Combina com outro iterador |
| `range.enumerate()` | `Range`, `RangeInclusive` | Adiciona índice |
| `range.map(f)` | `Range`, `RangeInclusive` | Transforma elementos |
| `range.filter(f)` | `Range`, `RangeInclusive` | Filtra elementos |

## Exemplos Práticos

### 1. Ranges em For Loops

```rust
fn main() {
    // Range exclusivo: 0, 1, 2, 3, 4
    print!("0..5:   ");
    for i in 0..5 {
        print!("{} ", i);
    }
    println!();

    // Range inclusivo: 1, 2, 3, 4, 5
    print!("1..=5:  ");
    for i in 1..=5 {
        print!("{} ", i);
    }
    println!();

    // Range reverso
    print!("Rev:    ");
    for i in (1..=5).rev() {
        print!("{} ", i);
    }
    println!();

    // Range com passo (step_by)
    print!("Step 2: ");
    for i in (0..10).step_by(2) {
        print!("{} ", i);
    }
    println!();

    // Range de caracteres
    print!("a..=f:  ");
    for c in 'a'..='f' {
        print!("{} ", c);
    }
    println!();

    // Contagem regressiva (countdown)
    print!("10..1:  ");
    for i in (1..=10).rev() {
        print!("{} ", i);
    }
    println!("Lançar!");

    // Usando range com variáveis
    let inicio = 5;
    let fim = 10;
    let soma: i32 = (inicio..=fim).sum();
    println!("\nSoma de {}..={}: {}", inicio, fim, soma); // 45
}
```

### 2. Ranges para Fatiamento de Slices e Strings

```rust
fn main() {
    let dados = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100];

    // Fatias com diferentes tipos de range
    let primeiros = &dados[..3];       // [10, 20, 30]
    let meios = &dados[3..7];          // [40, 50, 60, 70]
    let ultimos = &dados[7..];         // [80, 90, 100]
    let ate_5 = &dados[..=4];          // [10, 20, 30, 40, 50]
    let tudo = &dados[..];             // todos os elementos

    println!("Primeiros 3: {:?}", primeiros);
    println!("Do 4o ao 7o: {:?}", meios);
    println!("Últimos 3: {:?}", ultimos);
    println!("Até 5o (incl.): {:?}", ate_5);
    println!("Tudo: {:?}", tudo);

    // Fatiamento de strings
    let texto = "Olá, Mundo!";
    let ola = &texto[..5]; // cuidado: índices em bytes, não caracteres!
    let mundo = &texto[6..11];
    println!("{} -> {}", ola, mundo);

    // Fatiamento de Vec
    let mut vetor = vec![1, 2, 3, 4, 5];
    let fatia = &vetor[1..4];
    println!("Fatia do Vec: {:?}", fatia); // [2, 3, 4]

    // Modificar fatia
    for elem in &mut vetor[2..] {
        *elem *= 10;
    }
    println!("Vetor modificado: {:?}", vetor); // [1, 2, 30, 40, 50]
}
```

### 3. contains — Verificação de Pertinência

```rust
fn main() {
    // contains funciona com todos os tipos de range
    let faixa = 10..50;
    println!("25 em 10..50? {}", faixa.contains(&25));  // true
    println!("50 em 10..50? {}", faixa.contains(&50));  // false (exclusivo!)
    println!("50 em 10..=50? {}", (10..=50).contains(&50)); // true (inclusivo!)

    // Ranges abertos
    println!("5 em ..10? {}", (..10).contains(&5));   // true
    println!("15 em 10..? {}", (10..).contains(&15));  // true

    // Com caracteres
    let minusculas = 'a'..='z';
    let maiusculas = 'A'..='Z';
    let digitos = '0'..='9';

    let c = 'R';
    if maiusculas.contains(&c) {
        println!("'{}' é maiúscula", c);
    }

    // Classificar caracteres
    for ch in "Rust 2026!".chars() {
        let tipo = if ('a'..='z').contains(&ch) || ('A'..='Z').contains(&ch) {
            "letra"
        } else if digitos.contains(&ch) {
            "dígito"
        } else {
            "outro"
        };
        println!("  '{}' -> {}", ch, tipo);
    }
}
```

### 4. Ranges com Iteradores

```rust
fn main() {
    // collect para criar coleções
    let numeros: Vec<i32> = (1..=10).collect();
    println!("1..=10: {:?}", numeros);

    // map + collect
    let quadrados: Vec<i32> = (1..=5).map(|x| x * x).collect();
    println!("Quadrados: {:?}", quadrados); // [1, 4, 9, 16, 25]

    // filter + collect
    let pares: Vec<i32> = (1..=20).filter(|x| x % 2 == 0).collect();
    println!("Pares: {:?}", pares);

    // Operações de agregação
    let soma: i64 = (1..=100).sum();
    let produto: i64 = (1..=10).product();
    let contagem = (1..=1000).filter(|x| x % 7 == 0).count();

    println!("Soma 1..=100: {}", soma);      // 5050
    println!("Produto 1..=10: {}", produto);   // 3628800 (10!)
    println!("Múltiplos de 7 até 1000: {}", contagem);

    // zip com dois ranges
    let pares: Vec<(i32, i32)> = (0..5).zip(10..15).collect();
    println!("Zip: {:?}", pares);
    // [(0, 10), (1, 11), (2, 12), (3, 13), (4, 14)]

    // enumerate (equivalente a zip com 0..)
    for (i, letra) in ('a'..='e').enumerate() {
        println!("  {}: {}", i, letra);
    }

    // Criar string com range
    let alfabeto: String = ('A'..='Z').collect();
    println!("Alfabeto: {}", alfabeto);

    // flat_map com ranges
    let tabuada: Vec<String> = (1..=3)
        .flat_map(|a| (1..=3).map(move |b| format!("{}x{}={}", a, b, a * b)))
        .collect();
    println!("Tabuada: {:?}", tabuada);
}
```

### 5. Ranges em Coleções Ordenadas (BTreeMap/BTreeSet)

```rust
use std::collections::BTreeMap;
use std::collections::BTreeSet;

fn main() {
    // BTreeMap com range queries
    let mut temperaturas: BTreeMap<u32, f64> = BTreeMap::new();
    for hora in 0..24 {
        let temp = 15.0 + 10.0 * ((hora as f64 - 14.0) / 12.0 * std::f64::consts::PI).sin();
        temperaturas.insert(hora, (temp * 10.0).round() / 10.0);
    }

    // Temperatura entre 8h e 18h
    println!("Temperaturas do dia (8h-18h):");
    for (hora, temp) in temperaturas.range(8..=18) {
        println!("  {:2}h: {:.1}°C", hora, temp);
    }

    // BTreeSet com range
    let numeros: BTreeSet<i32> = (1..=100).collect();

    // Números entre 40 e 50
    let faixa: Vec<&i32> = numeros.range(40..=50).collect();
    println!("\nNúmeros 40-50: {:?}", faixa);

    // Contar elementos em uma faixa
    let qtd = numeros.range(1..=25).count();
    println!("Quantidade 1-25: {}", qtd);

    // Range em match
    let nota = 7;
    let conceito = match nota {
        0..=3 => "Insuficiente",
        4..=5 => "Regular",
        6..=7 => "Bom",
        8..=9 => "Muito Bom",
        10 => "Excelente",
        _ => "Inválido",
    };
    println!("\nNota {}: {}", nota, conceito);
}
```

## Características de Desempenho

Ranges são **zero-cost abstractions** em Rust. O compilador otimiza loops com ranges para o mesmo código de máquina que um loop C com contador.

```rust
// Estas duas versões geram código de máquina idêntico:

// Versão Rust idiomática
fn soma_range(n: i64) -> i64 {
    (1..=n).sum()
}

// Versão "manual"
fn soma_manual(n: i64) -> i64 {
    let mut total = 0;
    let mut i = 1;
    while i <= n {
        total += i;
        i += 1;
    }
    total
}

fn main() {
    println!("{}", soma_range(100));  // 5050
    println!("{}", soma_manual(100)); // 5050
}
```

| Aspecto | Custo |
|---|---|
| Criação de range | O(1), sem alocação |
| Iteração `for x in a..b` | O(b-a), zero overhead |
| `contains` | O(1) — simples comparação |
| `count` | O(1) para Range, O(n) para filtrado |
| `sum` | O(n) para iteração, O(1) se otimizado |
| Fatiamento `&arr[a..b]` | O(1) — retorna ponteiro + tamanho |

**Memória:** Um `Range<i32>` ocupa apenas 8 bytes (dois i32). Um `RangeInclusive<i32>` ocupa 12 bytes (dois i32 + flag de exaustão). Ranges não alocam memória no heap.

## Ranges vs Outras Formas de Iteração

| Abordagem | Quando Usar |
|---|---|
| `for i in 0..n` | Iteração por índice |
| `for x in &coleção` | Iteração por referência |
| `for x in coleção` | Iteração consumindo (move) |
| `(0..n).map(f)` | Transformação funcional |
| `(0..n).filter(f)` | Filtragem |
| `loop { ... }` | Loop infinito com controle manual |

## Veja Também

- [Slices em Rust](/stdlib/slice/) --- fatias de dados que usam ranges para indexação
- [Iterator em Rust](/stdlib/iterator/) --- trait Iterator usado por ranges
- [Arrays em Rust](/stdlib/arrays/) --- arrays de tamanho fixo fatiáveis com ranges
- [BTreeMap: Mapa Ordenado](/stdlib/btreemap/) --- range queries com mapas
- [BTreeSet: Conjunto Ordenado](/stdlib/btreeset/) --- range queries com conjuntos
- [Variáveis, Tipos e Funções](/tutoriais/variaveis-tipos-funcoes/) --- fundamentos de tipos e loops
