В Rust компилятор позволяет предотвратить случайные ошибки, связанные с типами данных. В связи с этим мы не можем просто взять и присвоить переменной одного типа значение другого типа. Например:
fn main(){
let int16: i16 = 123;
println!("int16: {}", int16);
let int32 : i32 = int16;
println!("int32: {}", int32); // Ошибка
}
В данном случае сначала определяется переменная int16, которая представляет тип i16 (то есть число со знаком размером в 16 бит). Затем ее значение присваивается переменной int32 - тоже целое число со знаком, только большей разрядности. Кажется, что здесь не должно быть никаких проблем, так как переменная int32 больше чем int16 и вполне может вместить ее значение. Однако при компиляции программы мы получим ошибку:
error[E0308]: mismatched types --> main.rs:4:23 | 4 | let int32 : i32 = int16; | --- ^^^^^ expected `i32`, found `i16` | | | expected due to this | help: you can convert an `i16` to an `i32` | 4 | let int32 : i32 = int16.into(); | +++++++ error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0308`.
Однако существуют ситуации, когда необходимо явно преобразовать числовые типы. Для преобразования между типами можно применять оператор as:
значение_для_преобразования as тип_в_который_преобразуем
Например, перепишем предыдущую программу с использованием оператора as:
fn main(){
let int16: i16 = 123;
println!("int16: {}", int16); // int16: 123
let int32 : i32 = int16 as i32; // преобразуем int32 в тип i32
println!("int32: {}", int32); // int32: 123
}
Теперь консольный вывод будет следующим
int16: 123 int32: 123
Важно понимать, что преобразование чисел может привести к неточным результатам или проблемам переполнения. Например:
fn main(){
let int16: i16 = 258;
println!("int16: {}", int16); // int16: 258
let int8 : i8 = int16 as i8; // преобразуем int32 в тип i8
println!("int8: {}", int8); // int8: 2
}
Здесь при преобразовании int16 в тип i8 из числа 258 мы получаем число 2, так как число 258 не укладывается в диапазон значений типа i8, соответственно идет усечение. То же самое касается и преобразований между целочисленными типами и типа чисел с плавающей точкой:
fn main() {
let float: f64 = 3.14;
let integer: i32 = float as i32; // преобразуем float в i32
println!(“integer: {}”, integer); // integer: 3
}