Fácil Rust

Empréstimo imutável

Enunciado

Escreva uma função primeira_palavra que recebe uma referência imutável a uma String e retorna a primeira palavra (até o primeiro espaço) como uma String nova. No main, crie uma String, chame a função e imprima o resultado. O dono original deve continuar válido após a chamada.

Requisitos

  • A função deve aceitar &String (ou &str) como parâmetro.
  • O main deve criar a String e passar uma referência &.
  • Após a chamada, a String original deve ser usada novamente (por exemplo, impressa).
  • A saída deve mostrar a primeira palavra e depois a string completa.

Código inicial

fn primeira_palavra(s: &String) -> String {
    // complete aqui
}

fn main() {
    let texto = String::from("Rust é divertido");
    // chame a função e imprima
}

Saída esperada

Primeira palavra: Rust
Texto completo: Rust é divertido
Ver dica

Use s.split_whitespace().next() para pegar a primeira palavra e converta para String com .to_string() ou .to_owned().

Mostrar solução
fn primeira_palavra(s: &String) -> String {
    // split_whitespace divide por espaços e next pega o primeiro
    s.split_whitespace().next().unwrap_or("").to_string()
}

fn main() {
    let texto = String::from("Rust é divertido");
    let palavra = primeira_palavra(&texto); // empréstimo imutável
    println!("Primeira palavra: {}", palavra);
    println!("Texto completo: {}", texto); // texto ainda é dono
}

Passo a passo

  1. A função primeira_palavra recebe s: &String, ou seja, um empréstimo imutável. Ela não pode modificar a string original.
  2. s.split_whitespace() cria um iterador que separa a string por espaços em branco.
  3. .next() pega o primeiro item do iterador, que é a primeira palavra. Se a string estiver vazia, retorna None.
  4. .unwrap_or("") trata o caso None retornando uma string vazia.
  5. .to_string() cria uma nova String com o conteúdo da palavra, para poder retorná-la sem depender do empréstimo.
  6. No main, criamos texto e chamamos primeira_palavra(&texto). O & cria a referência imutável.
  7. Depois da chamada, texto continua válido e pode ser impresso novamente, pois o empréstimo terminou.

Por que funciona

O borrow checker permite múltiplos empréstimos imutáveis simultâneos. Como a função só lê a string, não há conflito. O empréstimo termina quando a função retorna, então o dono original pode ser usado novamente.

Erros comuns

  • Esquecer o & na chamada: primeira_palavra(texto) move a String para a função, e depois texto não pode mais ser usado. O compilador acusa use of moved value.
  • Tentar modificar a string dentro da função: se você escrever s.push('!') dentro de primeira_palavra, o compilador reclama que s é imutável (cannot borrow as mutable).
  • Retornar uma referência para dados locais: se a função retornasse &str apontando para um buffer local, o compilador acusaria missing lifetime specifier ou returns a value referencing data owned by the current function. Por isso criamos uma String nova.

Outra forma de resolver

Usar &str em vez de &String é mais idiomático, pois aceita tanto String quanto literais:

fn primeira_palavra(s: &str) -> String {
    s.split_whitespace().next().unwrap_or("").to_string()
}

Saída esperada

Primeira palavra: Rust
Texto completo: Rust é divertido