Fácil Rust

Corrigindo move de String

Enunciado

O código abaixo tenta usar s1 depois de mover seu valor para s2. Corrija-o para que compile sem erros, mantendo ambas as variáveis válidas. Use .clone() para criar uma cópia independente.

Requisitos

  • O programa deve compilar sem erros.
  • Ambas as variáveis s1 e s2 devem ser impressas.
  • A saída deve mostrar os mesmos conteúdos originais.

Código inicial

fn main() {
    let s1 = String::from("ferrugem");
    let s2 = s1; // move
    println!("s1 = {}, s2 = {}", s1, s2);
}

Saída esperada

s1 = ferrugem, s2 = ferrugem
Ver dica

Substitua a atribuição direta por let s2 = s1.clone(); para copiar o valor em vez de mover.

Mostrar solução
fn main() {
    let s1 = String::from("ferrugem");
    let s2 = s1.clone(); // cria cópia profunda, s1 continua dono
    println!("s1 = {}, s2 = {}", s1, s2);
}

Passo a passo

  1. String::from("ferrugem") cria uma String no heap e a variável s1 se torna sua dona.
  2. s1.clone() chama o método clone da String, que aloca uma nova string no heap com o mesmo conteúdo.
  3. O resultado do clone é atribuído a s2, que se torna dona dessa nova alocação.
  4. s1 permanece válida porque não houve move; apenas uma cópia foi feita.
  5. O println! usa ambas as variáveis sem problemas.
  6. No fim do escopo, s1 e s2 são liberadas automaticamente via drop.

Por que funciona

O método .clone() realiza uma cópia profunda para tipos que implementam Clone, como String. Diferente do move, que transfere a posse, o clone mantém o dono original intacto. Assim, ambas as variáveis podem ser usadas independentemente.

Erros comuns

  • Esquecer o .clone() e tentar usar s1 após o move: o compilador emite error[E0382]: borrow of moved value: s1.
  • Usar .to_string() em vez de .clone(): funciona, mas é menos idiomático para cópia de String.
  • Achar que let s2 = s1; copia a string: na verdade move a posse, invalidando s1.

Outra forma de resolver

Se você não precisa de duas posses, pode passar referências:

fn main() {
    let s1 = String::from("ferrugem");
    let s2 = &s1; // empréstimo imutável
    println!("s1 = {}, s2 = {}", s1, s2);
}

Isso é preferível quando você só quer ler o valor sem copiar.

Saída esperada

s1 = ferrugem, s2 = ferrugem