Rust 入門 (三)_上

這部分咱們學習 rust 語言的 變量、數據類型、函數、註釋、流程控制 這五個方面的內容。本文咱們介紹前兩個內容,下一篇文章介紹後三個內容。編程

變量

默認狀況下,rust 語言中聲明的變量是不可變的,好比以下代碼:數組

fn main() {
    let x = 5;
    println!("x 的值是: {}", x);
    x = 6;
    println!("x 的值是: {}", x);
}

咱們先來跑一下這段代碼:安全

cargo run                                                                                                                                                                                         
   Compiling hello_cargo v0.1.0 (/Users/shanpengfei/work/rust-work-space/study/hello_cargo)
error[E0384]: cannot assign twice to immutable variable `x`
 --> src/main.rs:4:5
  |
2 |     let x = 5;
  |         -
  |         |
  |         first assignment to `x`
  |         help: make this binding mutable: `mut x`
3 |     println!("x 的值是: {}", x);
4 |     x = 6;
  |     ^^^^^ cannot assign twice to immutable variable

error: aborting due to previous error

For more information about this error, try `rustc --explain E0384`.

經過運行結果,咱們發現這段代碼有問題的,而後咱們從報錯信息中抓取關鍵信息:cannot assign twice to immutable variable,它的意思是 不可變變量不能進行二次賦值。可是有些時候,咱們也須要修改變量的值,應該怎麼辦呢,在變量名的前面,let 關鍵字的後面添加一個關鍵字 mut 就好了,咱們來試試:編程語言

fn main() {
    let mut x = 5;
    println!("x 的值是: {}", x);
    x = 6;
    println!("x 的值是: {}", x);
}

運行一下代碼:函數

cargo run                                                                                                                                                                                      
   Compiling hello_cargo v0.1.0 (/Users/shanpengfei/work/rust-work-space/study/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 3.53s
     Running `target/debug/hello_cargo`
x 的值是: 5
x 的值是: 6

這種不可變變量的設計有着不少安全方面的考慮,這裏再也不贅述。談到這裏,很容易聯想到編程語言的另外一個概念——常量,那兩者有什麼區別呢?
1.常量不能使用 mut 關鍵字修飾,常量在任何狀況下都是不可變的(變量是在默認狀況下不可變)。
2.常量使用 const 關鍵字來聲明,而變量使用 let 關鍵字來聲明。
3.常量須要在常量名後面緊跟冒號和類型,例如 const MAX_POINTS: u32 = 100_000;,而變量能夠省略冒號和類型的修飾。
4.常量的做用域是任何做用域,包括全局做用域。
5.常量只能使用常量表達式賦值,而不能使用函數結果或者其它運行時產生的值。學習

注:這是說明一下,常量一般使用大寫字母和下劃線 _ 來命名。this



咱們再來講一個變量的特性——覆蓋。在上一篇寫猜數字遊戲的文章中,咱們作數字類型轉換的時候,新類型的名字使用了舊類型的名字,這種狀況就是覆蓋。先來個實例:spa

fn main() {
    let x = 5;
    println!("x 的值是: {}", x);
    let x = 6;
    println!("x 的值是: {}", x);
}

咱們來看運行結果:debug

cargo run                                                                                                                                                                                          
   Compiling hello_cargo v0.1.0 (/Users/shanpengfei/work/rust-work-space/study/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.36s
     Running `target/debug/hello_cargo`
x 的值是: 5
x 的值是: 6

經過結果能夠發現,第二個使用 let 關鍵字修飾的不可變變量 x 把第一個 x 覆蓋了,也就是說把 x 的值從 5 改爲了 6。那這和 mut 有什麼區別呢?
1.覆蓋的第二個變量須要使用 let 關鍵字修飾,若是沒有 let 關鍵字,則會報錯。
2.覆蓋的第二個變量不只能夠改變值,還能夠修改變量的類型;而 mut 不能夠改變類型。設計

這裏舉兩個例子來講明第二個區別:

fn main() {
    let space = "abc";
    println!("space 表明的是:{}", space);
    let space = space.len();
    println!("space 表明的是:{}", space);
}

先來運行第一個例子:

cargo run                                                                                                                                                                                          
   Compiling hello_cargo v0.1.0 (/Users/shanpengfei/work/rust-work-space/study/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.22s
     Running `target/debug/hello_cargo`
space 表明的是:abc
space 表明的是:3

而後看第二個例子:

fn main() {
    let mut space = "abc";
    println!("space 表明的是:{}", space);
    space = space.len();
    println!("space 表明的是:{}", space);
}

跑一下第二個例子:

cargo run                                                                                                                                                                                         
   Compiling hello_cargo v0.1.0 (/Users/shanpengfei/work/rust-work-space/study/hello_cargo)
error[E0308]: mismatched types
 --> src/main.rs:4:13
  |
4 |     space = space.len();
  |             ^^^^^^^^^^^ expected &str, found usize
  |
  = note: expected type `&str`
             found type `usize`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
error: could not compile `hello_cargo`.

To learn more, run the command again with --verbose.

能夠輕易看到兩者的區別,好了,接下來咱們看 rust 的基本類型。

數據類型

rust 的數據類型就是在編譯期間告訴 rust 的編譯器如何處理這些數據。在這裏,咱們會了解到兩種數據類型:基本數據類型和組合數據類型。

基本數據類型

基本數據類型也就是簡單值,rust 主要包含了 4 種基本數據類型,分別是整型、浮點型、布爾型和字符型。你可能在其餘語言中見過這些類型,如今,咱們來看一下它們在 rust 語言中是怎麼樣的。

整型

整型是不包含小數的數字類型。整型包含了兩種類型:i 打頭的有符號整型和 u 打頭的無符號整型。咱們使用一個表格來描述 rust 的整型:


|佔用空間 |有符號整型 |無符號整型|
|:--:|:--:|:--:|
|8-bit |i8 |u8
|16-bit |i16 |u16
|32-bit |i32 |u32
|64-bit |i64 |u64
|128-bit |i128 |u128
|格式 |i+長度 |u+長度

整型在使用過程當中默認類型是 i32。

浮點型

浮點型包含了兩種類型:單精度浮點型 f32,雙精度浮點型 f64。浮點型在使用過程當中默認類型是 f64。

數據操做

rust 支持的基本數據操做有:加 +,減 -,乘 *,除 /,取模 %。

布爾型

布爾型一般有兩個值:true和false。它佔用 1 個字節,使用 bool 關鍵字來聲明。

字符型

rust 的字符類型佔用 4 個字節,它的值是使用單引號 ' 引發來的。

組合數據類型

組合數據類型是把多個值組合成一個類型。在 rust 中,組合數據類型有兩種:元組和數組。

元組

元組是把多個基本類型組合成一個組合類型。它有一個肯定的長度,一旦肯定就不能再次加減元素了。咱們先來看一個元組的實例:

fn main() {
    let tup: (i32, f64, u8) = (500, 6.4, 1);
    println!("第0個值:{}, 第1個值:{}, 第2個值:{}", tup.0, tup.1, tup.2);

    let (x, y, z) = tup;
    println!("x的值:{}, y的值:{}, z的值:{}", x, y, z);
}

它運行的結果是:

cargo run                                                                                                                                                                                          
   Compiling hello_cargo v0.1.0 (/Users/shanpengfei/work/rust-work-space/study/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.23s
     Running `target/debug/hello_cargo`
第0個值:500, 第1個值:6.4, 第2個值:1
x的值:500, y的值:6.4, z的值:1

元組的取值有兩種方式,一種是把元組解構成多個變量,另外一種就是使用 . 的方式,順序是從 0 開始。

數組

數組和元組不同的地方是:數組只能使用相同的數據類型。數組和元組相同的地方是:長度一旦肯定就不能加減元素了。若是想改變數組的長度,能夠使用 vector 類型,後續文章會介紹 vector 類型的狀況。並且數組還有一個特性,它會把數據分配到棧內存,而不是堆內存。下面舉幾個經常使用的數組的例子:

fn main() {
    // 定義一個簡單的數組
    let a = [1, 2, 3, 4, 5];

    // 定義一年 12 個月,並且不須要增減月份,那麼能夠直接定義包含 12 個月份的數組
    let months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];

    // 定義包含 5 個元素的 i32 類型的數組
    let a: [i32; 5] = [1, 2, 3, 4, 5];

    // 數組的值是 5 個 3
    let a = [3; 5];

    // 取值
    println!("a[3]的值是:{}", a[3]);
    println!("a[9]的值是:{}", a[9]);  // 編譯時這裏會報錯:error: index out of bounds: the len is 5 but the index is 9
}

數組的取值方式是以中括號 [0] 的方式,順序是從 0 開始。若是取值越界,rust 會在編譯期告訴你,這就是 rust 安全原則的第一個例子。


這一節未完,待續~~~

歡迎閱讀單鵬飛的學習筆記

相關文章
相關標籤/搜索