u32转换bool类型_4.29.类型转换
類型轉換
casting-between-types.md
commit 6ba952020fbc91bad64be1ea0650bfba52e6aab4
Rust,和它對安全的關注,提供了兩種不同的在不同類型間轉換的方式。第一個,as,用于安全轉換。相反,transmute允許任意的轉換,而這是 Rust 中最危險的功能之一!
強制轉換(Coercion)
類型間的強制轉換是隱式的并沒有自己的語法,不過可以寫作as。
強轉出現在let,const和static語句;函數調用參數;結構體初始化的字符值;和函數返回值中。
最常用的強轉的例子是從引用中去掉可變性:
&mut T到&T
一個相似的轉換時去掉一個[裸指針](Raw Pointers 裸指針.md)的可變性:
*mut T到*const T
引用也能被強轉為裸指針:
&T到*const T
&mut T到*mut T
自定義強轉可以用[Deref](Deref coercions Deref強制多態.md)定義。
強轉是可傳遞的。
as
as關鍵字進行安全的轉換:
let x: i32 = 5;
let y = x as i64;
有三種形式的安全轉換:顯式轉換,數字類型之間的轉換,和指針轉換。
轉換并不是可傳遞的:即便是e as U1 as U2是一個有效的表達式,e as U2也不必要是(事實上只有在U1強轉為U2時才有效)。
顯式轉換(Explicit coercions)
e as U是有效的僅當e是T類型而且T能強轉為U。
數值轉換
e as U的轉換在如下情況下也是有效的:
e是T類型而且T和U是任意數值類型:numeric-cast
e是一個類 C 語言枚舉(變量并沒有附加值),而且U是一個整型:enum-cast
e是bool或char而且T是一個整型:prim-int-cast
e是u8而且U是char:u8-char-cast
例如:
let one = true as u8;
let at_sign = 64 as char;
let two_hundred = -56i8 as u8;
數值轉換的語義是:
兩個相同大小的整型之間(例如:i32->u32)的轉換是一個no-op
從一個大的整型轉換為一個小的整型(例如:u32->u8)會截斷
從一個小的整型轉換為一個大的整型(例如:u8->u32)會
如果源類型是無符號的會補零(zero-extend)
如果源類型是有符號的會符號(sign-extend)
從一個整型轉換為一個浮點會產生整型的浮點表示,如有必要會舍入(未指定舍入策略)
從 f32 轉換為 f64 是完美無缺的
指針轉換
你也許會驚訝,[裸指針](Raw Pointers 裸指針.md)與整型之間的轉換是安全的,而且不同類型的指針之間的轉換遵循一些限制。只有解引用指針是不安全的:
let a = 300 as *const char; // a pointer to location 300
let b = a as u32;
e as U在如下情況是一個有效的指針轉換:
e是*T類型,U是*U_0類型,且要么U_0: Sized要么unsize_kind(T) == unsize_kind(U_0):ptr-ptr-cast
e是*T類型且U是數值類型,同時T: Sized:ptr-addr-cast
e是一個整型且U是*U_0類型,同時U_0: Sized:addr-ptr-cast
e是&[T; n]類型且U是*const T類型:array-ptr-cast
e是函數指針且U是*T類型,同時T: Sized:fptr-ptr-cast
e是函數指針且U是一個整型:fptr-addr-cast
transmute
as只允許安全的轉換,并會拒絕例如嘗試將 4 個字節轉換為一個u32:
let a = [0u8, 0u8, 0u8, 0u8];
let b = a as u32; // four eights makes 32
這個錯誤為:
error: non-scalar cast: `[u8; 4]` as `u32`
let b = a as u32; // four eights makes 32
^~~~~~~~
這是一個“非標量轉換(non-scalar cast)”因為這里我們有多個值:四個元素的數組。這種類型的轉換是非常危險的,因為他們假設多種底層結構的實現方式。為此,我們需要一些更危險的東西。
transmute函數由[編譯器固有功能](Intrinsics 固有功能.md)提供,它做的工作非常簡單,不過非常可怕。它告訴Rust對待一個類型的值就像它是另一個類型一樣。它這樣做并不管類型檢查系統,并完全信任你。
在我們之前的例子中,我們知道一個有4個u8的數組可以正常代表一個u32,并且我們想要進行轉換。使用transmute而不是as,Rust允許我們:
use std::mem;
unsafe {
let a = [0u8, 0u8, 0u8, 0u8];
let b = mem::transmute::(a);
}
為了使它編譯通過我們要把這些操作封裝到一個unsafe塊中。技術上講,只有mem::transmute調用自身需要位于塊中,不過在這個情況下包含所有相關的內容是有好處的,這樣你就知道該看哪了。在這例子中,a的細節也是重要的,所以它們放到了塊中。你會看到各種風格的代碼,有時上下文離得太遠,因此在unsafe中包含所有的代碼并不是一個好主意。
雖然transmute做了非常少的檢查,至少它確保了這些類型是相同大小的,這個錯誤:
use std::mem;
unsafe {
let a = [0u8, 0u8, 0u8, 0u8];
let b = mem::transmute::(a);
}
和:
error: transmute called with differently sized types: [u8; 4] (32 bits) to u64
(64 bits)
除了這些,你可以自行隨意轉換,只能幫你這么多了!
總結
以上是生活随笔為你收集整理的u32转换bool类型_4.29.类型转换的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sw二次开发 python_基于C#的S
- 下一篇: 哔哩哔哩swot分析_哔哩哔哩2020校