Cow (Clone-on-Write)
Cow<'a, T> é um emprestado &'a T ou possuído T - clona na escrita quando a mutação é necessária.
Receita
use std::borrow::Cow;
fn maybe_upper(s: Cow<str>) -> Cow<str> {
if s.contains("urgent") {
Cow::Owned(s.to_uppercase())
} else {
s
}
}Quando usar: APIs que aceitam &str ou String e, às vezes, precisam de mutação possuída.
Exemplo de Funcionamento
use std::borrow::Cow;
fn append_suffix<'a>(s: Cow<'a, str>, suffix: &str) -> Cow<'a, str> {
if suffix.is_empty() { return s; }
let mut owned = s.into_owned();
owned.push_str(suffix);
Cow::Owned(owned)
}
fn main() {
let borrowed = Cow::Borrowed("hello");
let owned = append_suffix(borrowed, "!");
println!("{owned}");
}O que isto demonstra:
into_ownedconverte um empréstimo em uma cópia possuída, se necessário.- A mutação aciona a alocação apenas quando necessário.
- Retornar
Cowevita forçar o chamador a alocar.
Mergulho Profundo
Cow<str>, Cow<[u8]>, Cow<OsStr> são comuns. Implementa Deref para o alvo.
Armadilhas
into_ownedclona o emprestado - Custo na primeira mutação. Correção: Aceite o custo ou useStringantecipadamente.- Tempo de vida ligado ao empréstimo - O
Cowretornado pode precisar de um ramo possuído'static. - Uso excessivo de
Cow- Complexidade versus sobrecargas deString/&str. Correção:impl AsRef<str>é mais simples às vezes. Cowem struct - Tempo de vida na struct. Correção: FrequentementeStringpossuída em structs armazenadas.serdecomCow- Geralmente desserializa para possuído.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
&str + sobrecargas de String | Duas APIs claras | Muitas APIs combinadas |
Arc<str> | Imutável compartilhado | Mutação de possuidor único |
Sempre String | Simples | Caminho de acesso quente (hot path) de empréstimo |
FAQs
Cow clona?
Clona o interior se necessário.to_mut?
Referência mutável forçando clone se emprestado.Eq?
Compara o conteúdo independentemente da variante.from?
Cow::from(&str) etc.match cow?
Braços emprestados vs. possuídos.fn aceita?
fn f(s: CowAPI de caminho?
Cow<OsStr> para caminhos.no_std?
cow com alocação.perf?
Vantagem quando raramente se muta.clippy?
dicas `unnecessary_to_owned`.Relacionados
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+.