原生類型

像其他現代編程語言一樣,Rust提供了一系列基礎的類型,我們一般稱之為原生類型。其強大的類型系統就是建立在這些原生類型之上的,因此,在寫Rust代碼之前,必須要對Rust的原生類型有一定的瞭解。

bool

Rust自帶了bool類型,其可能值為true或者false。 我們可以通過這樣的方式去聲明它:

let is_she_love_me = false;
let mut is_he_love_me: bool = true;

當然,bool類型被用的最多的地方就是在if表達式裡了。

char

在Rust中,一個char類型表示一個Unicode字符,這也就意味著,在某些語言裡代表一個字符(8bit)的char,在Rust裡實際上是四個字節(32bit)。 同時,我們可以將各種奇怪的非中文字符隨心所欲的賦值給一個char類型。需要注意的是,Rust中我們要用'來表示一個char,如果用"的話你得到的實際上是一個&'static str

let c = 'x';
let cc = '王';

數字類型

和其他類C系的語言不一樣,Rust用一種符號+位數的方式來表示其基本的數字類型。可能你習慣了intdoublefloat之類的表示法,Rust的表示法需要你稍微適應一下。

你可用的符號有 ifu

你可用的位數,當然了,都是2的n次冪,分別為8163264size

你可以將其組合起來,形成諸如i32,u16等類型。

當然了,這樣的組合並不自由,因為浮點類型最少只能用32位來表示,因此只能有f32f64來表示。

自適應類型

看完上面你一定會對isizeusize很好奇。這兩個是來幹啥的。這兩個嘛,其實是取決於你的操作系統的位數。簡單粗暴一點比如64位電腦上就是64位,32位電腦上就是32位,16位……呵呵噠。

但是需要注意的是,你不能因為你的電腦是64位的,而強行將它等同於64,也就是說isize != i64,任何情況下你都需要強制轉換。

數組 array

Rust的數組是被表示為[T;N]。其中N表示數組大小,並且這個大小一定是個編譯時就能獲得的整數值,T表示泛型類型,即任意類型。我們可以這麼來聲明和使用一個數組:

let a = [8, 9, 10];
let b: [u8;3] = [8, 6, 5];
print!("{}", a[0]);

和Golang一樣,Rust的數組中的N(大小)也是類型的一部分,即[u8; 3] != [u8; 4]。這麼設計是為了更安全和高效的使用內存,當然了,這會給第一次接觸類似概念的人帶來一點點困難,比如以下代碼。

fn show(arr: [u8;3]) {
    for i in &arr {
        print!("{} ", i);
    }
}

fn main() {
    let a: [u8; 3] = [1, 2, 3];
    show(a);
    let b: [u8; 4] = [1, 2, 3, 4];
    show(b);
}

編譯運行它你將獲得一個編譯錯誤:

<anon>:11:10: 11:11 error: mismatched types:
 expected `[u8; 3]`,
    found `[u8; 4]`
(expected an array with a fixed size of 3 elements,
    found one with 4 elements) [E0308]
<anon>:11     show(b);
                   ^
<anon>:11:10: 11:11 help: see the detailed explanation for E0308
error: aborting due to previous error

這是因為你將一個4長度的數組賦值給了一個只需要3長度數組作為參數的函數。那麼如何寫一個通用的show方法來展現任意長度數組呢?請看下節Slice

Slice

Slice從直觀上講,是對一個Array的切片,通過Slice,你能獲取到一個Array的部分或者全部的訪問權限。和Array不同,Slice是可以動態的,但是呢,其範圍是不能超過Array的大小,這點和Golang是不一樣的。

一個Slice的表達式可以為如下: &[T] 或者 &mut [T]

這裡&符號是一個難點,我們不妨放開這個符號,簡單的把它看成是Slice的甲魚臀部——規定。另外,同樣的,Slice也是可以通過下標的方式訪問其元素,下標也是從0開始的喲。 你可以這麼聲明並使用一個Slice

let arr = [1, 2, 3, 4, 5, 6];
let slice_complete = &arr[..]; // 獲取全部元素
let slice_middle = &arr[1..4]; // 獲取中間元素,最後取得的Slice為 [2, 3, 4] 。切片遵循左閉右開原則。
let slice_right = &arr[1..]; // 最後獲得的元素為[2, 3, 4, 5, 6],長度為5。
let slice_left = &arr[..3]; // 最後獲得的元素為[1, 2, 3],長度為3。

怎麼樣,瞭解了吧。 那麼接下來我們用Slice來改造一下上面的函數

fn show(arr: &[u8]) {
    for i in arr {
        print!("{} ", i);
    }
    println!("");
}

fn main() {
    let a: [u8; 3] = [1, 2, 3];
    let slice_a = &a[..];
    show(slice_a);
    let b: [u8; 4] = [1, 2, 3, 4];
    show(&b[..]);
}

輸出

1 2 3
1 2 3 4

動態數組 Vec

熟悉C++ STL的同學可能對C++的vector很熟悉,同樣的,Rust也提供了一個類似的東西。他叫Vec

在基礎類型裡講Vec貌似是不太合適的,但在實際應用中的應用比較廣泛,所以說先粗略的介紹一下,在集合類型的章節會有詳細講述。

在Rust裡,Vec被表示為 Vec<T>, 其中T是一個泛型。

下面介紹幾種典型的Vec的用法:

let mut v1: Vec<i32> = vec![1, 2, 3]; // 通過vec!宏來聲明
let v2 = vec![0; 10]; // 聲明一個初始長度為10的值全為0的動態數組
println!("{}", v1[0]); // 通過下標來訪問數組元素

for i in &v1 {
    print!("{}", i); // &Vec<i32> 可以通過 Deref 轉換成 &[i32]
}

println!("");

for i in &mut v1 {
    *i = *i+1;
    print!("{}", i); // 可變訪問
}

輸出結果:

1
123
234

最原生字符串 str

你可以用str來聲明一個字符串,事實上,Rust中,所有用""包裹起來的都可以稱為&str(注意這個&,這是難點,不用管他,不是麼?),但是這個類型被單獨用的情況很少,因此,我們將在下一節著重介紹字符串類型。

函數類型 Functions

函數同樣的是一個類型,這裡只給大家普及一些基本的概念,函數類型涉及到比較高階的應用,希望大家能在後面的閉包章節仔細參讀

下面是一個小例子

fn foo(x: i32) -> i32 { x+1 }

let x: fn(i32) -> i32 = foo;

assert_eq!(11, x(10));

results matching ""

    No results matching ""