Referências Compartilhadas

Uma referência fornece uma maneira de acessar outro valor sem assumir a responsabilidade pelo valor, e também é chamada de “empréstimo”. Referências compartilhadas são somente leitura e os dados referenciados não podem ser alterados.

fn main() {
    let a = 'A';
    let b = 'B';
    let mut r: &char = &a;
    println!("r: {}", *r);
    r = &b;
    println!("r: {}", *r);
}

Uma referência compartilhada a um tipo T tem tipo &T. Um valor de referência é feito com o operador &. O operador * “desreferencia” uma referência, produzindo seu valor.

Rust estaticamente proibirá referências pendentes:

fn x_axis(x: &i32) -> &(i32, i32) {
    let point = (*x, 0);
    return &point;
}
This slide should take about 10 minutes.
  • Uma referência é dita que “borrow” (empresta) o valor a que se refere, e este é um bom modelo para estudantes não familiarizados com ponteiros: o código pode usar a referência para acessar o valor, mas ainda é “owned” (propriedade) da variável original. O curso entrará em mais detalhes sobre ownership no dia 3.

  • Referências são implementadas como ponteiros, e uma vantagem chave é que podem ser muito menores do que a coisa a que apontam. Os alunos familiarizados com C ou C++ reconhecerão referências como ponteiros. Partes posteriores do curso abordarão como o Rust impede os bugs de segurança de memória que vêm do uso de ponteiros brutos.

  • O Rust não cria automaticamente referências para você - o & é sempre necessário.

  • Em alguns casos, o Rust desreferenciará automaticamente, em particular ao invocar métodos (tente r.is_ascii()). Não há necessidade de um operador -> como em C++.

  • Neste exemplo, r é mutável para que possa ser reatribuído (r = &b). Observe que isso re-associa r, de modo que se refere a outra coisa. Isso é diferente do C++, onde a atribuição a uma referência altera o valor referenciado.

  • Uma referência compartilhada não permite modificar o valor a que se refere, mesmo que esse valor seja mutável. Tente *r = 'X'.

  • O Rust está rastreando os tempos de vida de todas as referências para garantir que elas vivam tempo suficiente. Referências pendentes não podem ocorrer em Rust seguro. x_axis retornaria uma referência a point, mas point será desalocado quando a função retornar, então isso não será compilado.

  • Falaremos mais sobre empréstimos quando chegarmos à ownership.