<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>

                Borrowing 繼續講講另一個重要的概念:借用(borrowing), 什么是借用? 我們先來看前一文章(\[[易學易懂系列|rustlang語言|零基礎|快速入門|(3)\]](https://www.cnblogs.com/gyc567/p/11910013.html))的代碼 : ~~~ let a = [1, 2, 3]; ? let b = a; ? println!("{:?} {:?}", a, b); *// [1, 2, 3] [1, 2, 3]* ? let a = vec![1, 2, 3]; ? let b = a; ? println!("{:?} {:?}", a, b); *// Error; use of moved value: `a`* ~~~ 我們從上篇文章知道,第二段代碼會報錯,那怎么才能不報錯呢? 我們改成以下代碼: ~~~ let a = vec![1, 2, 3]; ? let b = **&**a;//這里加了一個符號:**&**,表示借用 ? println!("{:?} {:?}", a, b); *// correct* ~~~ 現在可以順利通過傲嬌的編程器女王的檢查了!這就是“借用”的功效! 這里就出來一個rust語言的概念,叫借用(borrowing)。 來看下定義: 英語:[Borrow (verb)](https://github.com/nikomatsakis/rust-tutorials-keynote/blob/master/Ownership%20and%20Borrowing.pdf)To receive something with the promise of returning it. 翻譯成中文:出來混,借了東西,遲早要還的! 那借用又分兩類型: 1.共享借用(**Shared Borrowing**`(&T)`) 數據可以借用給一個或多個用戶(或線程),但只準一個用戶修改。 2.可變借用(**Mutable Borrowing**`(&mut T)`) 數據可以借用給一個用戶,并只準這個用戶修改,同時不準其他用戶訪問。 借用規則如下 : 1.數據同一時間,只能是其中一種借用,要么是共享借用(**Shared Borrowing**`(&T)`),要么是可變借用(**Mutable Borrowing**`(&mut T)`)。 2.借用概念適用于復制類型(Copy type )和移動類型(**Move type**)。 請看如下代碼: ~~~ fn main() { ?let mut a = vec![1, 2, 3]; ?let b = &mut a; ?// &mut borrow of `a` starts here ? ? ? ? ? ? ? ? ? // ? ?// some code ? ? // ? ?// some code ? ? // ? } ? ? ? ? ? ? ? ? ?// &mut borrow of `a` ends here ? ? fn main() { ?let mut a = vec![1, 2, 3]; ?let b = &mut a; ?// &mut borrow of `a` starts here ?// some code ? ?println!("{:?}", a); // trying to access `a` as a shared borrow, so giving an error } ? ? ? ? ? ? ? ? ?// &mut borrow of `a` ends here ? ? fn main() { ?let mut a = vec![1, 2, 3]; { ? ?let b = &mut a; ?// &mut borrow of `a` starts here ? ?// any other code } ? ? ? ? ? ? ? ? ?// &mut borrow of `a` ends here ? ?println!("{:?}", a); // allow borrowing `a` as a shared borrow } ~~~ 從上面代碼,我們可以看出,借用,也是有“生命周期”的。 像這段代碼 : ~~~ fn main() { ? ? ?let mut a = vec![1, 2, 3]; ? ?let b = &mut a; // &mut borrow of `a` starts here // some code ? ? ?println!("{:?}", a); // trying to access `a` as a shared borrow, so giving ? ? ? ? ? ? ? ? ? ? ? ? //an error } // &mut borrow of `a` ends here ~~~ 為什么會報錯?因為當最后一行代碼: ~~~ println!("{:?}", a); ~~~ 要訪問a時,a對數據的所有權,已經借用給b了。a已經沒有數據所有權。所以報錯。 那要怎么辦? 加上大括號“{}”。 如下 : ~~~ let mut a = vec![1, 2, 3]; { ? ?let b = &mut a; ?// &mut borrow of `a` starts here ? ?// any other code } ? ? ? ? ? ? ? ? ?// &mut borrow of `a` ends here ? ?println!("{:?}", a); // allow borrowing `a` as a shared borrow ~~~ 加上{}后,把借用,限定在大括號內,大括號結束后,b會把**所有權還給**a。 這時,a對數據有了所有權,就可以訪問數據了! 那共享借用和可變借用有什么區別呢,請看代碼如下 : 共享借用: ~~~ fn main() { ? ?let a = [1, 2, 3]; ? ?let b = &a; ? ?println!("{:?} {}", a, b[0]); // [1, 2, 3] 1 } ? ? fn main() { ? ?let a = vec![1, 2, 3]; ? ?let b = get_first_element(&a); ? ? ?println!("{:?} {}", a, b); // [1, 2, 3] 1 } ? fn get_first_element(a: &Vec<i32>) -> i32 { ? ?a[0] } ~~~ 第一段代碼: ~~~ fn main() { ? ?let a = [1, 2, 3]; ? ?let b = &a; ? ?println!("{:?} {}", a, b[0]); // [1, 2, 3] 1 } ~~~ 這里a借用給了b,為什么a還可以訪問呢?因為a的類型是數組,是基本類型。這是復制類型,共享借用,只借用復制數據。所以,原來a還是擁有對原始數據的所有權。 第二段代碼: ~~~ fn main() { ? ?let a = vec![1, 2, 3]; ? ?let b = get_first_element(&a); ? ? ?println!("{:?} {}", a, b); // [1, 2, 3] 1 } ? fn get_first_element(a: &Vec<i32>) -> i32 { ? ?a[0] } ~~~ 這里定義一個函數,get\_first\_element,返回值為數組中的第一個值。b從函數中得到值1。沒有什么問題。 現在我們修改一下函數get\_first\_element的代碼,如下 : ~~~ fn get_first_element(a: &Vec<i32>) -> i32 { ? a[0]=9; ? a[0] ? } ~~~ 這時,傲嬌的編譯器女王,又扔出一個錯誤給你: ~~~ fn get_first_element(a: &Vec<i32>) -> i32 { ? | --------- help: consider changing this to be a mutable reference: `&mut std::vec::Vec` ? | a[0]=9; | ? ? ^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable ~~~ 這些錯誤信息很清楚地告訴你: 你現在是共享借用,共享借用只能共享數據,不能修改!(這里的真實含義是:**共享借用了數據,沒有所有權,如果沒有所有權,就沒有修改權,只有擁有所有權,才有修改權!**) 那要修改怎么辦?用可變借用啊! 把代碼修改為如下就可以了: ~~~ fn main() { ? let mut a = vec![1, 2, 3]; let b = get_first_element(&mut a);//從函數get_first_element返回后,把數據所有權還給a ? ? println!("{:?} {}", a, b); // [9, 2, 3] 9 ? ? } ? fn get_first_element(g: &mut Vec<i32>) -> i32 { //開始借用 a的數據 ?g[0]=9; ?g[0] ? }//結束借用 a的數據,返回到main函數后,把數據所有權還給a ~~~ 以上代碼,已經把**不可變**變量a改為**可變**變量,**共享變量**&a改為**可變共享**&mut a。 在上面的代碼中,a所綁定的數據的**所有權(ownership)**已經**移動**(**move**),也就是說數據**所有權(ownership)**已經從a轉交到函數get\_first\_element的參數變量g,在函數get\_first\_element內,修改了數據的內容,然后返回main函數,并把數據所有權**還給**綁定變量a,這時數據內容已經更新。 所以打印結果為: ~~~ [9, 2, 3] 9 ~~~ 再看看可變借用完整例子: ~~~ fn main() { ? ?let mut a = [1, 2, 3]; ? ?let b = &mut a; ? ?b[0] = 4; ? ?println!("{:?}", b); // [4, 2, 3] } ? ? fn main() { ? ?let mut a = [1, 2, 3]; ? { ? ? ? ?let b = &mut a; ? ? ? ?b[0] = 4; ? } ? ? ?println!("{:?}", a); // [4, 2, 3] } ? ? fn main() { ? ?let mut a = vec![1, 2, 3]; ? ?let b = change_and_get_first_element(&mut a); ? ? ?println!("{:?} {}", a, b); // [4, 2, 3] 4 } ? fn change_and_get_first_element(a: &mut Vec<i32>) -> i32 { ? ?a[0] = 4; ? ?a[0] } ~~~ 所以,我們結合**所有權(Ownership)**和**借用(Borrowing)**兩個概念來理解。 得出來一個重要結論: 1.**沒有所有權,就沒有修改權,只有擁有所有權,才有修改權**。 2.**共享借用,不會轉交數據所有權,所以借用者,沒有修改權,借用者歸還數據所有權后,數據內容不變。** 3.**可變借用,會轉交數據所有權,所以借用者,擁有修改權,借用者歸還數據所有權后,數據內容可能已經改變**。 **4.這里的“借用”,其實可以跟“引用”劃上等號,共享借用,也就是共享引用(或不可變引用),可變借用,也就是可變引用,但它們都是跟數據所有權結合一起的。** 以上,希望對你有用。
                  <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>

                              哎呀哎呀视频在线观看