Menu
Coddy logo textTech

Operator znaku zapytania „?”

Część sekcji Logika i przepływ programu ścieżki Rust w Coddy. Lekcja 46 z 66.

Podczas pracy z funkcjami, które zwracają Result, często trzeba obsługiwać błędy, zajmując się nimi lokalnie lub przekazując je do funkcji wywołującej. Rust udostępnia elegancki operator do tego typowego wzorca: operator znaku zapytania ?.

Operator ? zapewnia przejrzysty sposób propagowania błędów bez pisania rozwlekłych instrukcji match. Gdy umieścisz ? po wartości typu Result, automatycznie wyodrębni wartość Ok lub natychmiast zwróci wartość z wariantem Err z bieżącej funkcji:

fn parse_and_double(s: &str) -> Result<i32, std::num::ParseIntError> {
    let number = s.parse::<i32>()?; // Jeśli parsowanie się nie powiedzie, zwróć błąd
    Ok(number * 2) // Jeśli się powiedzie, podwój liczbę
}

Jest to równoważne zapisaniu pełnej instrukcji match, ale znacznie zwięźlejsze. Jeśli s.parse::<i32>() zwróci Ok, operator ? wyodrębnia wartość i przypisuje ją do number. Jeśli zwróci Err, operator ? natychmiast zwraca ten błąd z całej funkcji.

Zwróć uwagę na składnię ::<i32>. Nazywa się ją turbofish i informuje Rust, na jaki typ należy sparsować ciąg znaków. Funkcja zwraca Result<i32, std::num::ParseIntError>, gdzie i32 jest typem wyniku w przypadku powodzenia, a std::num::ParseIntError jest typem błędu zwracanym, gdy parsowanie się nie powiedzie.

Operatora ? można używać tylko w funkcjach, które zwracają Result (lub Option), ponieważ musi on mieć możliwość zwrócenia błędu.

challenge icon

Wyzwanie

Łatwy

Otrzymasz dwa wejścia. Pierwsze wejście to łańcuch, który należy sparsować jako liczbę całkowitą, a drugie wejście to kolejny łańcuch, który również należy sparsować jako liczbę całkowitą. Utwórz funkcję o nazwie add_numbers, która przyjmuje dwa wycinki łańcuchów jako parametry i zwraca wartość typu Result<i32, std::num::ParseIntError>. Wewnątrz funkcji użyj operatora ?, aby sparsować oba łańcuchy, i zwróć ich sumę opakowaną w Ok. Wywołaj funkcję z dwoma wejściami i obsłuż wynik za pomocą match.

Wymagania:

  • Odczytaj pierwsze wejście (pierwszą liczbę jako łańcuch) i usuń białe znaki
  • Odczytaj drugie wejście (drugą liczbę jako łańcuch) i usuń białe znaki
  • Utwórz funkcję add_numbers, która przyjmuje dwa parametry typu &str i zwraca wartość typu Result<i32, std::num::ParseIntError>
  • Wewnątrz funkcji sparsuj pierwszy łańcuch do typu i32, używając operatora ?
  • Sparsuj drugi łańcuch do typu i32, używając operatora ?
  • Zwróć Ok(sum), gdzie sumą jest dodanie obu sparsowanych liczb
  • Wywołaj funkcję z dwoma łańcuchami wejściowymi
  • Użyj wyrażenia match, aby obsłużyć wartość typu Result
  • W ramieniu Ok(value) wypisz: Sum: [value]
  • W ramieniu Err(_) wypisz: Parsing error

Wejście:

  • Pierwszy wiersz: łańcuch reprezentujący liczbę (np. 15)
  • Drugi wiersz: łańcuch reprezentujący inną liczbę (np. 27)

Wyjście:

  • Jeśli oba łańcuchy są prawidłowymi liczbami: Sum: [result]
  • Jeśli nie można sparsować któregoś z łańcuchów: Parsing error

Spróbuj swoich sił

use std::io;

// TODO: Utwórz tutaj funkcję add_numbers
// Powinna przyjmować dwa parametry &str i zwracać Result<i32, std::num::ParseIntError>


fn main() {
    // Wczytaj pierwszą wartość wejściową
    let mut input1 = String::new();
    io::stdin().read_line(&mut input1).expect("Failed to read line");
    let input1 = input1.trim();
    
    // Wczytaj drugą wartość wejściową
    let mut input2 = String::new();
    io::stdin().read_line(&mut input2).expect("Failed to read line");
    let input2 = input2.trim();
    
    // TODO: Wywołaj add_numbers z input1 i input2
    // TODO: Użyj match do obsługi Result
    // Wypisz "Sum: [value]" dla Ok(value)
    // Wypisz "Parsing error" dla Err(_)
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Logika i przepływ programu

Poćwicz samodzielnie: Kompilator Rust online