這部分咱們學習 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 安全原則的第一個例子。
這一節未完,待續~~~
歡迎閱讀單鵬飛的學習筆記