Semântica de Move e Cópia
Atribuição e passagem por valor movem (transferem propriedade) ou copiam (duplicam bits) dependendo do tipo. Clone fornece duplicação explícita quando necessário.
Busque em todas as páginas da documentação
Atribuição e passagem por valor movem (transferem propriedade) ou copiam (duplicam bits) dependendo do tipo. Clone fornece duplicação explícita quando necessário.
#[derive(Clone, Debug)]
struct Config { host: String, port: u16 }
fn main() {
let port: u16 = 8080; // Cópia
let p2 = port;
let cfg = Config { host: "localhost".into(), port };
let cfg2 = cfg.clone(); // cópia profunda explícita
println!("{port} {:?} {:?}", cfg, cfg2);
}Quando usar isso: Decidir se um tipo deve ser Copy, quando usar clone(), e projetar APIs que movem vs. emprestam.
#[derive(Copy, Clone, Debug)]
struct Point { x: i32, y: i32 }
fn translate(p: Point, dx: i32) -> Point {
Point { x: p.x + dx, y: p.y }
}
fn main() {
let origin = Point { x: 0, y: 0 };
let moved = origin; // Cópia - ambos válidos
let shifted = translate(moved, 5);
println!("{origin:?} {shifted:?}");
}O que isso demonstra:
Point é Copy porque todos os campos são Copyorigin permanece utilizável após a atribuiçãoCopyString não pode ser Copy (propriedade do heap)Copy invalida o binding de origemVec, String, HashMap sempre movem na atribuiçãoCopy// Todos os campos Copy, sem impl Drop (geralmente)
#[derive(Copy, Clone)]
struct Flags(u32);Tipos com Drop customizado geralmente não podem ser Copy.
Clone vs Copy| Trait | Quando | Efeito |
|---|---|---|
Copy | Implícito na atribuição | Duplicação bit a bit |
Clone | .clone() explícito | Duplicação definida pelo usuário |
Clone em Coleçõeslet v1 = vec![1, 2];
let v2 = v1.clone(); // clona elementos se T: CloneCopy em struct com String - Erro de compilação. Correção: Remover Copy ou usar &str/Arc<str> se o compartilhamento for necessário.Vec - Ela move. Correção: Usar .clone() explicitamente quando a duplicata for necessária.Copy + Drop - Drop customizado significa que a semântica de move importa. Correção: Não implementar Copy.| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
Empréstimo &T | Acesso compartilhado somente leitura | Chamador deve reter propriedade para retorno |
Rc/Arc | Propriedade compartilhada sem clone profundo | Um único proprietário é mais claro |
Cow<'a, T> | Às vezes empresta, às vezes possui | Sempre um modo |
| Move apenas | A transferência é intencional | Chamadores precisam continuar usando o valor |
Para tipos Copy, sim. Para tipos de heap, move copia os metadados da stack (ponteiro, len, cap), não os dados do heap.
Sim com unsafe impl Copy, mas derivar é o padrão. Todos os campos devem ser Copy previamente.
A semântica de Clone é definida pelo tipo. Arc::clone apenas incrementa a contagem de referências.
i32 está inteiramente na stack sem propriedade. String possui alocação no heap.
[T; N] é Copy quando T: Copy. Arrays grandes são Copy mas caros para copiar bit a bit.
Use MaybeUninit em padrões unsafe. Código seguro usa valores totalmente inicializados.
Sim para tipos não-Copy. O otimizador pode elidir cópias na prática (NRVO).
Sim se os payloads de todas as variantes forem Copy.
Derivar percorre os campos recursivamente. Campos de heap clonam seus conteúdos.
Dados de propriedade movem para futures. Bounds Send governam moves entre threads.
Versões da Stack: Esta página foi escrita para Rust 1.97.0 (edição 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, e Polars 0.46+.
Revisado por Chris St. John·Última atualização: 19 de jul. de 2026