W Rust konwersja typów (type casting) jest realizowana za pomocą słowa kluczowego as. Umożliwia to jawne przekształcenie jednego typu na inny:
let x: i32 = 10; let y: u8 = x as u8;
Rust nie wykonuje niejawnych konwersji (implicit cast), jak na przykład C czy C++. Zapobiega to wielu błędom związanym z utratą danych lub przepełnieniem.
Cechy:
Potencjalne zagrożenia:
i32 na u8, jeśli wartość przekracza zakres, nadmiarowe bity są po prostu odrzucane — może to prowadzić do nieoczekiwanego zachowania.Przykład:
let big: u16 = 300; let small: u8 = big as u8; // small == 44, ponieważ 300 % 256 = 44
Co się stanie, jeśli wykonasz konwersję liczby ujemnej typu
i8na typu8za pomocą słowa kluczowegoas?
Odpowiedź: Wartość nie powoduje błędu kompilacji ani paniki w czasie wykonania. Zamiast tego bity wartości są interpretowane jako liczba bez znaku:
let x: i8 = -1; let y: u8 = x as u8; // y == 255
Historia
W aplikacji finansowej dane o kwotach przelewów początkowo były przechowywane jako i32. Programista postanowił przekształcić je na u32 bez sprawdzania granic, co prowadziło do nieprawidłowego przetwarzania wartości ujemnych — kwoty niespodziewanie stawały się dużymi liczbami dodatnimi, przechodząc walidację logiki biznesowej!
Historia
W grze na mikrokontrolery przełączanie poziomów przyspieszenia obliczano jako różnicę dwóch wartości poziomu: wynik mógł być ujemny. Użyto konwersji as u8 do zaokrąglenia wyniku, ignorując przepełnienia. W rezultacie prędkości „zawieszały się” na maksymalnym poziomie, ponieważ wartości ujemne przekształcały się w duże dodatnie z powodu zachowania wrap-around.
Historia
W aplikacji sieciowej podczas kopiowania bufora danych długość obliczano jako różnicę wskaźników (usize), a następnie konwertowano do u32 za pomocą as. Przy dużych ilościach pamięci (>4 GB) prowadziło to do ucięcia wartości, co powodowało obcinanie danych i błędy podczas przesyłania dużego pliku.