The Rust Book section on the as
operator currently says
The as keyword does basic casting:
let x: i32 = 5;
let y = x as i64;
It only allows certain kinds of casting, however.
What are those certain kinds of allowed casting?
A since-deleted answer here explained that sometimes you need to chain multiple as
-casts to accomplish a safe result, that can't be done in a single step. When is that necessary?
I don't think that this is documented very well, but here is some information you might find useful:
A cast
e as U
is valid if one of the following holds:
e
has typeT
andT
coerces toU
; coercion-caste
has type*T
,U
is*U_0
, and eitherU_0: Sized
or unsize_kind(T
) = unsize_kind(U_0
); ptr-ptr-caste
has type*T
andU
is a numeric type, whileT: Sized
; ptr-addr-caste
is an integer andU
is*U_0
, whileU_0: Sized
; addr-ptr-caste
has typeT
andT
andU
are any numeric types; numeric-caste
is a C-like enum andU
is an integer type; enum-caste
has typebool
orchar
andU
is an integer; prim-int-caste
has typeu8
andU
ischar
; u8-char-caste
has type&[T; n]
andU
is*const T
; array-ptr-caste
is a function pointer type andU
has type*T
, whileT: Sized
; fptr-ptr-caste
is a function pointer type andU
is an integer; fptr-addr-castwhere
&.T
and*T
are references of either mutability, and where unsize_kind(T
) is the kind of the unsize info inT
- the vtable for a trait definition (e.g.fmt::Display
orIterator
, notIterator<Item=u8>
) or a length (or()
ifT: Sized
).Note that lengths are not adjusted when casting raw slices -
T: *const [u16] as *const [u8]
creates a slice that only includes half of the original memory.Casting is not transitive, that is, even if
e as U1 as U2
is a valid expression,e as U2
is not necessarily so (in fact it will only be valid ifU1
coerces toU2
).
Quoted from The Rustonomicon: Casts
Here's an exhaustive list of all the true casts. For brevity, we will use * to denote either a *const or *mut, and integer to denote any integral primitive:
- *T as *U where T, U: Sized
- *T as *U TODO: explain unsized situation
- *T as integer
- integer as *T
- number as number
- C-like-enum as integer
- bool as integer
- char as integer
- u8 as char
- &[T; n] as *const T
- fn as *T where T: Sized
- fn as integer
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With