Slices

Uma slice (fatia) oferece uma visão de uma coleção maior:

fn main() {
    let mut a: [i32; 6] = [10, 20, 30, 40, 50, 60];
    println!("a: {a:?}");

    let s: &[i32] = &a[2..4];

    println!("s: {s:?}");
}
  • Slices pegam dados emprestados do tipo original.
  • Pergunta: O que acontece se você modificar a[3] imediatamente antes de imprimir s?
  • Nós criamos uma slice emprestando a e especificando os índices de início e fim entre colchetes.

  • Se a slice começa no índice 0, a sintaxe de range (faixa) nos permite omitir o índice inicial, o que significa que &a[0..a.len()] e &a[..a.len()] são idênticos.

  • O mesmo vale para o último índice, logo &a[2..a.len()] e &a[2..] são idênticos.

  • Para criar facilmente uma slice de uma matriz completa, podemos utilizar&a[..].

  • s é uma referência a uma slice de i32. Observe que o tipo de s (&[i32]) não menciona mais o tamanho da matriz. Isso nos permite realizar cálculos em slices de tamanhos diferentes.

  • As slices sempre pegam emprestado de outro objeto. Neste exemplo, a deve permanecer ‘vivo’ (em escopo) por pelo menos tanto tempo quanto nossa slice.

  • A questão sobre a modificação de a[3] pode gerar uma discussão interessante, mas a resposta é que por motivos de segurança de memória você não pode fazer isso por meio de a neste ponto durante a execução, mas você pode ler os dados de a e s com segurança. Isto funciona antes da criação do slice, e novamente depois de println, quando o slice não é mais necessário. Mais detalhes serão explicados na seção do verificador de empréstimos.