Conversion and Casting
Rust is statically-typed at compile time. Hence, after a variable is declared, assigning a value of a value of a different type (unless it's implicitly convertible to the target type) to the variable is prohibited. There are several ways to convert types in Rust.
Implicit conversions
Implicit conversions exist in JavaScript as well as in Rust (called type coercions). Consider the following example:
let intNumber = 1;
let longNumber = intNumber;
Rust is much more restrictive with respect to which type coercions are allowed:
let int_number: i32 = 1;
let long_number: i64 = int_number; // error: expected `i64`, found `i32`
An example for a valid implicit conversion using subtyping is:
fn bar<'a>() {
let s: &'static str = "hi";
let t: &'a str = s;
}
See also:
Explicit conversions
If converting could cause a loss of information, JavaScript requires explicit conversions using a casting expression:
let a = 1.2;
let b = parseInt(a);
Explicit conversions can potentially fail at run-time with exceptions when down-casting.
Rust does not provide coercion between primitive types, but instead uses explicit conversion using the as
keyword (casting). Casting in Rust will not cause a panic.
let int_number: i32 = 1;
let long_number: i64 = int_number as _;
Custom conversion
In Rust, the standard library contains an abstraction for converting a value into a different type, in form of the From
trait and its reciprocal, Into
. When implementing From
for a type, a default implementation for Into
is automatically provided (called blanket implementation in Rust). The following example illustrates two of such type conversions:
fn main() {
let my_id = MyId("id".into()); // `into()` is implemented automatically due to the `From<&str>` trait implementation for `String`.
println!("{}", String::from(my_id)); // This uses the `From<MyId>` implementation for `String`.
}
struct MyId(String);
impl From<MyId> for String {
fn from(MyId(value): MyId) -> Self {
value
}
}
See also: