Introdução
Mover uma String transfere a propriedade, mas muitas funções precisam apenas de acesso temporário. O Rust chama esse acesso temporário de empréstimo e o representa com uma referência.
Você concluirá um programa de lista de convidados já preparado em três pequenas etapas: inspecionar um texto próprio por meio de uma referência compartilhada, observar intencionalmente por que o acesso compartilhado não pode modificá-lo e, depois, fazer uma atualização controlada por meio de uma referência mutável. A saída final comprovará que main ainda é proprietário da lista e pode usá-la.
Inspecionar dados por meio de uma referência compartilhada
Nesta etapa, você emprestará a uma função acesso somente leitura a uma String, em vez de mover a propriedade para dentro dela.
Entre no projeto Cargo preparado e abra o código-fonte:
cd /home/labex/project/guest-borrowing
nano src/main.rs
A configuração criou o projeto completo e deixou um marcador de posição na chamada de inspect_guests. O tipo do parâmetro é &String. O símbolo & significa “uma referência a uma String”: a função pode visualizar o valor temporariamente, mas não se torna a proprietária dele.
Substitua somente /* Step 1: borrow guest_list */ por &guest_list, para que a chamada fique assim:
inspect_guests(&guest_list);
Aqui, &guest_list cria uma referência compartilhada. Compartilhada significa que o acesso somente leitura pode ser compartilhado sem transferir a própria String.
Salve pressionando Ctrl+O, pressione Enter e saia com Ctrl+X. Execute o programa:
cargo run --quiet
A saída deverá ser:
Inspecting: Ari, Bo
Caller still owns: Ari, Bo
Before update: Ari, Bo
Updated: Ari, Bo
A primeira linha vem da referência emprestada. A segunda linha é a evidência importante de propriedade: depois que inspect_guests retorna, main ainda pode usar guest_list. A função de atualização também lê o valor atual, mas ainda não o modifica.
Observar o limite de uma referência compartilhada
Nesta etapa, você tentará intencionalmente modificar a String por meio de uma referência compartilhada. A verificação malsucedida do compilador é esperada e fornece evidências da regra de empréstimo do Rust.
Abra o código-fonte novamente:
nano src/main.rs
Dentro de add_guest, remova somente o // inicial da linha preparada, para que ela fique assim:
list.push_str(", Mina");
O método push_str acrescenta texto a uma String, portanto precisa de permissão para modificar o valor. No entanto, list atualmente tem o tipo &String, que concede acesso compartilhado e somente leitura.
Salve e saia. Antes de verificar, preveja o resultado: o compilador deverá rejeitar a tentativa de modificação porque uma referência compartilhada não pode fornecer acesso mutável.
Execute a verificação. A falha é esperada:
cargo check
Localize estas partes estáveis do diagnóstico:
error[E0596]: cannot borrow `*list` as mutable, as it is behind a `&` reference
...
consider changing this to be a mutable reference
A expressão *list refere-se à String alcançada por meio da referência. O Rust não está dizendo que a String nunca pode mudar; está dizendo que essa &String específica não carrega permissão para modificá-la. Na próxima etapa, você concederá acesso mutável controlado.
Atualizar por meio de uma referência mutável
Nesta etapa, você dará a add_guest permissão temporária e exclusiva para modificar a String do chamador.
Uma referência mutável tem o formato &mut T. Uma regra útil para iniciantes é muitos leitores ou um escritor por vez: referências compartilhadas permitem a leitura, enquanto uma referência mutável concede acesso temporário e exclusivo de escrita. Essa exclusividade impede que duas partes do programa alterem o mesmo valor de forma inesperada.
Abra o arquivo:
nano src/main.rs
Faça três edições específicas:
- Altere o parâmetro de
add_guestde&Stringpara&mut String. - Adicione
mutà declaração, para que ela fiquelet mut guest_list = .... - Altere a chamada de
add_guestde&guest_listpara&mut guest_list.
A assinatura completa da função e a chamada deverão ter estas formas:
fn add_guest(list: &mut String) {
add_guest(&mut guest_list);
Os dois usos de mut têm funções relacionadas, mas diferentes. let mut guest_list indica que o valor próprio pode ser alterado. Em seguida, &mut guest_list cria uma referência mutável temporária que empresta acesso exclusivo de escrita a add_guest durante a chamada.
Salve e saia. Depois, verifique a correção:
cargo check
Um resultado Finished sem E0596 significa que as permissões agora são compatíveis. Execute o programa:
cargo run --quiet
A saída final deverá ser:
Inspecting: Ari, Bo
Caller still owns: Ari, Bo
Before update: Ari, Bo
Updated: Ari, Bo, Mina
O empréstimo mutável termina quando add_guest retorna. A impressão final pode ler guest_list novamente, comprovando que a propriedade permaneceu em main enquanto a função fazia uma atualização controlada.
Resumo
Você usou &String para obter acesso compartilhado e somente leitura, e &mut String para fazer uma modificação temporária e exclusiva. Nos dois casos, o chamador manteve a propriedade, e o compilador ajudou a impor a diferença entre visualizar e alterar dados emprestados.



