Referências e Slices
Referências emprestam dados sem tomar posse. Slices (&[T], &str) são visualizações emprestadas de sequências contíguas com comprimento em tempo de execução.
Receita
fn first_word(s: &str) -> &str {
match s.find(' ') {
Some(i) => &s[..i],
None => s,
}
}
fn main() {
let sentence = String::from("hello world");
println!("{}", first_word(&sentence));
}Quando usar isso: Parâmetros de função que apenas leem dados, extração de substrings e passagem de visualizações de array sem cópia.
Exemplo de Trabalho
fn sum_slice(nums: &[i32]) -> i32 {
nums.iter().sum()
}
fn window(data: &[i32], start: usize, len: usize) -> Option<&[i32]> {
data.get(start..start + len)
}
fn main() {
let arr = [10, 20, 30, 40];
println!("sum={}", sum_slice(&arr));
println!("{:?}", window(&arr, 1, 2));
}O que isso demonstra:
&[i32]aceita arrays eVecvia coerção- Fatiamento de intervalo
start..endem arrays e strings .get(range)retornaOptionem vez de entrar em pânico&strde&Stringvia coerção de desreferenciamento
Mergulho Profundo
Tipos de Referência
| Tipo | Acesso | Contagem por vez |
|---|---|---|
&T | Leitura compartilhada | Muitos |
&mut T | Escrita exclusiva | Um (sem & simultaneamente) |
Slices de String
let s = String::from("hello");
let slice: &str = &s[0..2]; // "he" - índices de byteUTF-8 significa que os índices de byte devem cair nos limites de caracteres ou o fatiamento entrará em pânico.
Slices de Array
let a = [1, 2, 3, 4];
let mid: &[i32] = &a[1..3]; // [2, 3]Padrões de Slice
fn head(tail: &[i32]) -> Option<(&i32, &[i32])> {
tail.split_first()
}Armadilhas
- Fatiar strings em um índice de byte arbitrário - Pode dividir um ponto de código UTF-8. Correção: Use
.chars()ouunicode-segmentationpara grafemas. - Retornar slice vinculado a
Stringlocal - Erro de tempo de vida. Correção: RetorneStringde propriedade ou pegue o proprietário como parâmetro. - Confundir
&Vec<T>com&[T]- Prefira&[T]em APIs. Correção: Use a forma de slice;&vecé coagido automaticamente. - Alias de slice mutável - Dois
&mutpara intervalos sobrepostos falham. Correção: Divida comsplit_at_mut. - Índice fora dos limites -
arr[99]entra em pânico. Correção: Use.get(99).
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
String/Vec de propriedade | O chamador transfere a propriedade | Inspeção somente leitura é suficiente |
Cow<'a, str> | Talvez empreste, talvez aloque | A propriedade é sempre clara |
| Índices + comprimento | Interoperabilidade FFI | APIs Rust seguras |
| Iteradores | Travessia preguiçosa | Acesso aleatório é necessário |
FAQs
O que é coerção de desreferenciamento?
&String é coagido para &str, &Vec<T> para &[T] em locais de chamada de função quando o destino espera um slice.
Slices podem estar vazios?
Sim. &[] e &s[0..0] são slices vazios válidos.
Qual o tamanho máximo de um slice?
len() é usize. Slices não podem exceder a alocação subjacente.
Os elementos do slice são copiados na passagem por valor?
Slices são referências (ponteiros gordos). Os elementos não são copiados.
Posso mutar através de `&mut [T]`?
Sim. slice[0] = 1 muta o array subjacente ou Vec.
Para que serve `as_ptr`?
Ponteiro de baixo nível para o primeiro elemento. Usado em unsafe/FFI, não em código de aplicação típico.
Como copio um slice?
slice.to_vec() para Vec de propriedade. slice.to_owned() quando T: Clone.
O `&str` pode ser nulo?
Não em Rust seguro. Use Option<&str> para ausência.
O que é um ponteiro largo?
Ponteiro gordo de slice/str armazena o ponteiro de dados mais o comprimento (duas palavras).
Como os tempos de vida aparecem aqui?
&str em um tipo de retorno precisa de um tempo de vida vinculado à entrada. Veja a seção de Posse.
Relacionados
- Preview de Posse - mover vs emprestar
- Empréstimos e Referências - regras de alias
- Vec & Slices - operações de vetor
- UTF-8 & Indexação - fatiamento seguro de strings
Versões da Pilha: 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+.