<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 類型轉換 > [casting-between-types.md](https://github.com/rust-lang/rust/blob/master/src/doc/book/casting-between-types.md) commit 6ba952020fbc91bad64be1ea0650bfba52e6aab4 Rust,和它對安全的關注,提供了兩種不同的在不同類型間轉換的方式。第一個,`as`,用于安全轉換。相反,`transmute`允許任意的轉換,而這是 Rust 中最危險的功能之一! ### 強制轉換(Coercion) 類型間的強制轉換是隱式的并沒有自己的語法,不過可以寫作[`as`](#)。 強轉出現在`let`,`const`和`static`語句;函數調用參數;結構體初始化的字符值;和函數返回值中。 最常用的強轉的例子是從引用中去掉可變性: - `&mut T`到`&T` 一個相似的轉換時去掉一個[裸指針](#)的可變性: - `*mut T`到`*const T` 引用也能被強轉為裸指針: - `&T`到`*const T` - `&mut T`到`*mut T` 自定義強轉可以用[`Deref`](#)定義。 強轉是可傳遞的。 ### `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) - 從一個浮點轉換為一個整型會向 0 舍入 - [注意:目前如果舍入的值并不能用目標整型表示的話會導致未定義行為(Undefined Behavior)](https://github.com/rust-lang/rust/issues/10184)。這包括 Inf 和 NaN。這是一個 bug 并會被修復。 - 從一個整型轉換為一個浮點會產生整型的浮點表示,如有必要會舍入(未指定舍入策略) - 從 f32 轉換為 f64 是完美無缺的 - 從 f64 轉換為 f32 會產生最接近的可能值(未指定舍入策略) - [注意:目前如果值是有限的不過大于或小于 f32 所能表示的最大最小值會導致未定義行為(Undefined Behavior)](https://github.com/rust-lang/rust/issues/10184)。這是一個 bug 并會被修復。 ### 指針轉換 你也許會驚訝,[裸指針](#)與整型之間的轉換是安全的,而且不同類型的指針之間的轉換遵循一些限制。只有解引用指針是不安全的: ~~~ 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`函數由[編譯器固有功能](#)提供,它做的工作非常簡單,不過非常可怕。它告訴Rust對待一個類型的值就像它是另一個類型一樣。它這樣做并不管類型檢查系統,并完全信任你。 在我們之前的例子中,我們知道一個有4個`u8`的數組可以正常代表一個`u32`,并且我們想要進行轉換。使用`transmute`而不是`as`,Rust允許我們: ~~~ use std::mem; unsafe { let a = [0u8, 0u8, 0u8, 0u8]; let b = mem::transmute::<[u8; 4], u32>(a); } ~~~ 為了使它編譯通過我們要把這些操作封裝到一個`unsafe`塊中。技術上講,只有`mem::transmute`調用自身需要位于塊中,不過在這個情況下包含所有相關的內容是有好處的,這樣你就知道該看哪了。在這例子中,`a`的細節也是重要的,所以它們放到了塊中。你會看到各種風格的代碼,有時上下文離得太遠,因此在`unsafe`中包含所有的代碼并不是一個好主意。 雖然`transmute`做了非常少的檢查,至少它確保了這些類型是相同大小的,這個錯誤: ~~~ use std::mem; unsafe { let a = [0u8, 0u8, 0u8, 0u8]; let b = mem::transmute::<[u8; 4], u64>(a); } ~~~ 和: ~~~ error: transmute called with differently sized types: [u8; 4] (32 bits) to u64 (64 bits) ~~~ 除了這些,你可以自行隨意轉換,只能幫你這么多了!
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看