---
title: "E0507: Não Pode Mover de Referência no Rust"
url: "https://rustlang.com.br/erros/e0507-mover-de-referencia/"
markdown_url: "https://rustlang.com.br/erros/e0507-mover-de-referencia.MD"
description: "Como resolver o erro E0507 do Rust: cannot move out of borrowed content. Aprenda a usar clone, take, swap e outras técnicas para resolver este erro comum."
date: "2026-02-23"
author: "Equipe Rust Brasil"
---

# E0507: Não Pode Mover de Referência no Rust

Como resolver o erro E0507 do Rust: cannot move out of borrowed content. Aprenda a usar clone, take, swap e outras técnicas para resolver este erro comum.


# E0507: Não Pode Mover de Referência

O erro **E0507** ocorre quando você tenta **mover** um valor para fora de uma referência emprestada. Referências no Rust são empréstimos temporários — você pode olhar e até modificar (com `&mut`), mas não pode **levar o valor embora**.

## A Mensagem de Erro

```
error[E0507]: cannot move out of `*item` which is behind a shared reference
 --> src/main.rs:4:17
  |
4 |     let valor = *item;
  |                 ^^^^^
  |                 |
  |                 move occurs because `*item` has type `String`, which does not implement the `Copy` trait
  |                 help: consider borrowing here: `&*item`
```

Outra variação comum:

```
error[E0507]: cannot move out of index of `Vec<String>`
 --> src/main.rs:3:15
  |
3 |     let nome = nomes[0];
  |               ^^^^^^^^
  |               |
  |               move occurs because value has type `String`, which does not implement the `Copy` trait
  |               help: consider borrowing here: `&nomes[0]`
```

## O Que Significa

Uma referência (`&T` ou `&mut T`) dá acesso temporário a um valor sem transferir o ownership. Tentar mover o valor de dentro da referência violaria a regra fundamental: **o dono original ainda espera que o valor esteja lá**.

Se fosse permitido "extrair" um valor de uma referência, o dono original ficaria com um buraco — memória não inicializada — o que é comportamento indefinido.

Este erro aparece frequentemente em três cenários:
1. Acessar elementos de uma coleção por índice (`vec[0]`)
2. Desreferenciar uma referência (`*ref_valor`)
3. Fazer pattern matching que move valores de dentro de structs emprestadas

## Código com Erro

```rust
fn main() {
    let nomes = vec![
        String::from("Alice"),
        String::from("Bob"),
        String::from("Carol"),
    ];

    // ERRO: tenta mover String de dentro do Vec
    let primeiro = nomes[0];
    println!("{}", primeiro);
}
```

Com structs:

```rust
struct Usuario {
    nome: String,
    email: String,
}

fn obter_nome(usuario: &Usuario) -> String {
    // ERRO: não pode mover `nome` de uma referência
    usuario.nome
}
```

## Como Resolver

### Solução 1: Usar `.clone()` para Copiar

A solução mais direta — crie uma cópia do valor:

```rust
fn main() {
    let nomes = vec![
        String::from("Alice"),
        String::from("Bob"),
    ];

    let primeiro = nomes[0].clone();
    println!("{}", primeiro);
    println!("Original: {:?}", nomes); // nomes continua intacto
}

fn obter_nome(usuario: &Usuario) -> String {
    usuario.nome.clone()
}
```

### Solução 2: Retornar uma Referência

Se você não precisa do ownership, retorne uma referência:

```rust
struct Usuario {
    nome: String,
    email: String,
}

fn obter_nome(usuario: &Usuario) -> &str {
    &usuario.nome
}

fn main() {
    let user = Usuario {
        nome: String::from("Alice"),
        email: String::from("alice@email.com"),
    };

    let nome = obter_nome(&user);
    println!("Nome: {}", nome);
}
```

### Solução 3: Usar `.take()` com `Option`

Quando o valor está dentro de um `Option` e você tem acesso mutável, use `.take()`:

```rust
fn main() {
    let mut valor: Option<String> = Some(String::from("dados"));

    // .take() retira o valor e deixa None no lugar
    let extraido = valor.take();

    println!("Extraído: {:?}", extraido); // Some("dados")
    println!("Original: {:?}", valor);    // None
}
```

### Solução 4: Usar `std::mem::swap` ou `std::mem::replace`

Quando precisa extrair um valor de uma referência mutável, substitua-o por outro valor:

```rust
use std::mem;

struct Fila {
    itens: Vec<String>,
}

impl Fila {
    fn drenar(&mut self) -> Vec<String> {
        // Troca `self.itens` por um Vec vazio, retornando o original
        mem::take(&mut self.itens)
    }
}

fn main() {
    let mut fila = Fila {
        itens: vec![String::from("a"), String::from("b")],
    };

    let itens = fila.drenar();
    println!("Drenados: {:?}", itens);
    println!("Fila agora: {:?}", fila.itens); // []
}
```

### Solução 5: Usar `remove()` ou `swap_remove()` em Vecs

Se você quer extrair um elemento específico de um `Vec`:

```rust
fn main() {
    let mut nomes = vec![
        String::from("Alice"),
        String::from("Bob"),
        String::from("Carol"),
    ];

    // Remove e retorna o elemento no índice 0
    let primeiro = nomes.remove(0);
    println!("Removido: {}", primeiro);
    println!("Restantes: {:?}", nomes);

    // swap_remove é mais rápido (O(1)) mas não preserva ordem
    let ultimo = nomes.swap_remove(0);
    println!("Removido: {}", ultimo);
}
```

## Quando Usar Cada Solução

| Situação | Solução Recomendada |
|---|---|
| Precisa apenas ler o valor | Retorne referência (`&T`) |
| Precisa de uma cópia independente | Use `.clone()` |
| Valor em `Option<T>` com `&mut` | Use `.take()` |
| Precisa substituir por valor padrão | Use `mem::take()` ou `mem::replace()` |
| Quer remover de uma coleção | Use `.remove()` ou `.swap_remove()` |

## Veja Também

- [E0382: Uso de Valor Após Move](/erros/e0382-uso-apos-move/)
- [E0505: Mover Valor Enquanto Emprestado](/erros/e0505-mover-valor-emprestado/)
- [Tutorial de Ownership e Borrowing](/tutoriais/ownership-borrowing/)
- [Cheatsheet Rust](/cheatsheet/)
- [Documentação oficial: E0507](https://doc.rust-lang.org/error_codes/E0507.html)
