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

                **變量綁定** * * * 我們現在回過頭來看看,一些基礎知識。 因為理解了前面的重要概念:所有權,借用,生命周期。 我們現在看基礎知識就很簡單了。 先看變量定義: ~~~ let a = true;//rust不要求顯式定義類型,編譯器女王自動會根據上下文和用途,來自動定義類型,這里 ? ? ? ? ? ? //是:bool let b: bool = true;//如果顯式定義類型,則通過:分號+類型 ? let (x, y) = (1, 2); ? let mut z = 5; z = 6; ~~~ 在rust,這些變量定義叫變量綁定。 為什么這樣說?因為rust的變量,默認是不可變的。 如果,要變成可變變量,要用關鍵字:mut。 那如果是常量呢? 看代碼: 常量(const): ~~~ const N: i32 = 5; ~~~ 靜態變量(static): ~~~ static N: i32 = 5; ~~~ 常量與靜態變量的區別是: 1.常量const在內存沒有固定地址,而靜態變量static的地址是固定的。 2.靜態變量一般用在全局變量,一般寫在代碼最上方,在函數體外,常量可以定義在函數內。 3.一般最好用const來定義常量,因為它地址不是固定的,可以讓編譯器優化。 布爾值(bool): ~~~ let x = true; let y: bool = false; ? // ?? no TRUE, FALSE, 1, 0 ~~~ 字符(char): ~~~ let x = 'x'; let y = '??'; ? // ?? no "x", only single quotes ~~~ 布爾值,類型關鍵字:bool,值:true 或者false,注意是小寫。 字符類型,用的是單引號。因為rust是從底層支持unicode,所以char**占位4 byte**。 數組(arrays): ~~~ let a = [1, 2, 3]; // a[0] = 1, a[1] = 2, a[2] = 3 let mut b = [1, 2, 3]; ? let c: [i32; 0] = []; //[Type; NO of elements] -> [] /empty array let d: [i32; 3] = [1, 2, 3]; ? let e = ["my value"; 3]; //["my value", "my value", "my value"]; ? println!("{:?}", a); //[1, 2, 3] println!("{:#?}", a); ~~~ 數組主要用來存放相同類型的數據,它的**長度是固定的,也是默認不可變的(長度和內容都不可變)**。如果,用mut來定義,它的長度也是不可變的,但數組內的數據可以變。 如果我想緩存一些不同類型的數據,怎么辦? 用元組(tuples): ~~~ let a = (1, 1.5, true, 'a', "Hello, world!"); // a.0 = 1, a.1 = 1.5, a.2 = true, a.3 = 'a', a.4 = "Hello, world!" ? let b: (i32, f64) = (1, 1.5); ? let (c, d) = b; // c = 1, d = 1.5 let (e, _, _, _, f) = a; //e = 1, f = "Hello, world!", _ indicates not interested of that item ? let g = (0,); //single-element tuple ? let h = (b, (2, 4), 5); //((1, 1.5), (2, 4), 5) ? println!("{:?}", a); //(1, 1.5, true, 'a', "Hello, world!") ~~~ 元組主要用來存放不同類型的數據,它的**長度是固定的,也是默認不可變的(長度和內容都不可變)**。如果,用mut來定義,它的長度也是不可變的,數組內的數據可以變,但**變化的值與之前的值的類型要保持一致**。 切片(slice): ~~~ let a: [i32; 4] = [1, 2, 3, 4];//Parent Array ? let b: &[i32] = &a; //Slicing whole array let c = &a[0..4]; // From 0th position to 4th(excluding) let d = &a[..]; //Slicing whole array ? let e = &a[1..3]; //[2, 3] let f = &a[1..]; //[2, 3, 4] let g = &a[..3]; //[1, 2, 3] ~~~ 切片,要rust中來說,就是其他數據結構(主要是數組)的**可變長度**的引用或視圖。 字符串(str): ~~~ let a = "Hello, world."; //a: &'static str let b: &str = "你好, 世界!"; ~~~ 在rust,str類型準確來說,是字符串切片。是最基本的字符串類型。 我們來看看下面兩種寫法是一樣的: ~~~ let hello = "Hello, world!"; ? // with an explicit type annotation let hello: &'static str = "Hello, world!"; ~~~ 我們看到,hello變量的生命周期注解是:'static,說明它的生命周期是跟整個程序的生命周期一樣。 它是借用類型:&str,說明它是從字符串 "Hello, world!",借用過來的。 當然它還有一種寫法: ~~~ let hello = String::from("Hello, world!"); let mut hello = String::from("Hello, "); ? hello.push('w'); hello.push_str("orld!"); ~~~ 這里直接用方法:**String::from()**來構建。 str 和 String之間的區別: **1.String是一個可變的、堆(heap)上分配的UTF-8的字節符串。** **2.str是字符串切片,就像vector 切片一樣,它包括:指針+長度,也就是說它是一個字符串變量(這個字符串已經從堆heap上分配內存,像String類型數據或字面值數據string literal )的“視圖”;如果是從String解引用而來的,則指向堆上,如果是字面值,則指向靜態內存。** 一般來說, 如果你相擁有所有權(ownership),就用String定義; 如果想直接借用(沒有所有權,有借就要有還),就用&str; 注意:**字符串String是堆(heap)分配的,它是不定長的。** 說到這里,我想再深入來講講在Rust語言中String的內存分配原理。這很有意思。 其實,跟java一樣,String都是從堆heap里分配內存的。我們來看看代碼吧: ~~~ let s1 = String::from("hello");//從堆heap分配內存給"hello",并綁定到s1 let s2 = s1; println!("{}, world!", s1); ~~~ 第一行代碼: ~~~ let s1 = String::from("hello");//從堆heap分配內存給"hello",并綁定到s1 ~~~ 在Rust里的內存分配是這樣的: ![](https://img2018.cnblogs.com/blog/544318/201911/544318-20191127101814013-579940571.png) Rust在stack里分配一個空間給s1,分別存放: 1.指向堆heap地址的指針:ptr 2.長度變量len 3.容量變更capacity 現在我們看第二行代碼: ~~~ let s2 = s1; ~~~ 把s1綁定到s2,Rust也會在棧stack分配內存空間給s2(因為stack內存分配是簡單且成本低的,運行時runtime會及時回收),而我們知道Rust中的**所有權**概念,所以這時數據的所有權從s1**移動**到s2,如下圖: ![](https://img2018.cnblogs.com/blog/544318/201911/544318-20191127101801992-1533746401.png) 從上圖可以看出,現在s1已經沒有對數據"hello"擁有所有權,所以第三行代碼: ~~~ println!("{}, world!", s1);//complier error ~~~ 編譯器女王會給你一個錯誤 : ~~~ error[E0382]: use of moved value: `s1` --> src/main.rs:5:28 | 3 | ? ? let s2 = s1; | ? ? ? ? -- value moved here 4 | 5 | ? ? println!("{}, world!", s1); | ? ? ? ? ? ? ? ? ? ? ? ? ? ^^ value used here after move | ?= note: move occurs because `s1` has type `std::string::String`, which does ?not implement the `Copy` trait ~~~ 那要怎么樣,才不會報錯呢?用clone: ~~~ let s1 = String::from("hello"); let s2 = s1.clone(); ? println!("s1 = {}, s2 = {}", s1, s2); ~~~ 它在內存中的分配,是這樣的: ![](https://img2018.cnblogs.com/blog/544318/201911/544318-20191127101747366-2109015280.png) 以上,希望對你有用。
                  <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>

                              哎呀哎呀视频在线观看