原生類型
像其他現代編程語言一樣,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用一種符號+位數的方式來表示其基本的數字類型。可能你習慣了int
、double
、float
之類的表示法,Rust的表示法需要你稍微適應一下。
你可用的符號有 i
、f
、u
你可用的位數,當然了,都是2的n次冪,分別為8
、16
、32
、64
及size
。
你可以將其組合起來,形成諸如i32
,u16
等類型。
當然了,這樣的組合並不自由,因為浮點類型最少只能用32位來表示,因此只能有f32
和f64
來表示。
自適應類型
看完上面你一定會對isize
和usize
很好奇。這兩個是來幹啥的。這兩個嘛,其實是取決於你的操作系統的位數。簡單粗暴一點比如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));