Rust zapewnia wygodne standardowe środki do konwersji ciągów znaków na liczby za pomocą traitu FromStr. Najczęściej używaną metodą jest .parse::<T>(), którą można wywołać na ciągach i wycinkach.
W wielu językach konwersja ciągu znaków na liczbę to powszechne zadanie, ale w Rust odbywa się to maksymalnie bezpiecznie i przejrzyście, błędy przetwarzania są częścią kontraktu standardowej biblioteki, a nie wyjątkami czasu wykonania.
.parse::<T>() zwraca wynik typu Result<T, ParseIntError> (lub podobny dla innych typów), co zmusza do jawnej obsługi niepowodzeń. Częstym błędem jest ignorowanie możliwości błędu, używanie unwrap() bez analizy, co grozi awarią programu przy nieprawidłowym wprowadzeniu danych, a nie rzetelnym komunikatem o błędzie.
Do konwersji ciągów znaków używa się metody parse. Jej sygnatura:
let num: i32 = "42".parse().unwrap();
Ale lepiej jest obsłużyć błąd:
let s = "abc"; match s.parse::<i32>() { Ok(n) => println!("Otrzymana liczba: {}", n), Err(e) => println!("Błąd parsowania: {e}"), }
Kluczowe cechy:
FromStr, ale dokładne ograniczenia są niejawne: spacje, znaki, przepełnienia są traktowane różnieResult, a nie przez panikę lub wyjątekFromStr (w tym użytkowników) może być celem .parse()Czy można używać parse bez podawania typu wyniku?
Nie, bez sprecyzowania typu (lub niejawnego wydedukowania typu) Rust zgłosi błąd, ponieważ nie rozumie, do jakiego typu dokonać konwersji.
Co się stanie, jeśli spróbujesz sparsować ciąg z niecyfrową zawartością na liczbę?
Metoda zwróci błąd (Err(...)), nie spowoduje paniki. Błąd realizuje trait Debug, co ułatwia wyjście.
let num: Result<u32, _> = "not_a_number".parse(); assert!(num.is_err());
Czy można używać unwrap po parse, jeśli jesteśmy pewni zawartości?
Technicznie tak, ale to antywzorzec. Jeśli ciąg niespodziewanie jest niewłaściwy, program awaryjnie się zakończy.
unwrap() bez obsługi błędówtrim przed konwersją, jeśli wejście pochodzi od użytkownikaparse::<String>()) zamiast docelowego typu liczbowegoKonsolowa narzędzie odczytuje liczbę od użytkownika i używa .parse().unwrap(). Przy przypadkowym nieprawidłowym wprowadzeniu program nagle pada, użytkownik nie rozumie przyczyny.
Zalety:
Wady:
Wejście najpierw jest czyszczone z spacji, a parse jest używane w scenariuszu z match lub jeśli to konieczne — map_err, aby zwrócić własny błąd. Błędy są poprawnie obsługiwane, wyświetlane jest wyraźne komunikat o błędzie.
Zalety:
Wady: