Ответ 1
Я не думаю, что это задокументировано очень хорошо, но здесь - это некоторая информация, которая может вам пригодиться:
Листинг
e as U
действителен, если выполнено одно из следующих действий:
e
имеет типT
иT
приводит кU
; принуждении литаяe
имеет тип*T
,U
-*U_0
, и либоU_0: Sized
, либо unsize_kind (T
) = unsize_kind (U_0
); PTR-PTR-литаяe
имеет тип*T
, аU
- числовой тип, аT: Sized
; PTR-адр-литаяe
- целое число, аU
-*U_0
, аU_0: Sized
; адр-PTR-литаяe
имеет типT
иT
иU
- любые числовые типы; Числовой-литаяe
является C-подобным перечислением, аU
является целым типом; Перечисление-литаяe
имеет типbool
илиchar
иU
- целое число; прима-ИНТ-литаяe
имеет типu8
иU
ischar
; u8- char Литойe
имеет тип&[T; n]
иU
is*const T
; массив PTR-литаяe
- это тип указателя функции, аU
имеет тип*T
, аT: Sized
; fptr-PTR-литаяe
- это тип указателя функции, аU
- целое число; fptr-адр-литаягде
&.T
и*T
являются ссылками любой изменчивости, и где unsize_kind (T
) - это тип unsize info вT
- vtable для определения признака (например,fmt::Display
илиIterator
, а неIterator<Item=u8>
) или длину (или()
, еслиT: Sized
).Обратите внимание, что при отбрасывании сырых срезов длины не корректируются -
T: *const [u16] as *const [u8]
создает срез, который включает только половину исходной памяти.Кастинг не является транзитивным, то есть даже если
e as U1 as U2
является действительным выражение,e as U2
не обязательно так (на самом деле оно будет справедливо только в том случае, еслиU1
приближается кU2
).