# 原生類型
> [primitive-types.md](https://github.com/rust-lang/rust/blob/master/src/doc/book/primitive-types.md)
commit 6ba952020fbc91bad64be1ea0650bfba52e6aab4
Rust有一系列被認為是“原生”的類型。這意味著它們是內建在語言中的。Rust被構建為在標準庫中也提供了一些建立在這些類型之上的有用的類型,不過它們也大部分是原生的。
### 布爾型
Rust 有一個內建的布爾類型,叫做`bool`。它有兩個值,`true`和`false`:
~~~
let x = true;
let y: bool = false;
~~~
布爾型通常用在[if語句](#)中。
你可以在[標準庫文檔](http://doc.rust-lang.org/nightly/std/primitive.bool.html)中找到更多關于`bool`的文檔。
### `char`
`char`類型代表一個單獨的 Unicode 字符的值。你可以用單引號(`'`)創建`char`:
~~~
let x = 'x';
let two_hearts = '?';
~~~
不像其它語言,這意味著Rust的`char`并不是 1 個字節,而是 4 個。
你可以在[標準庫文檔](http://doc.rust-lang.org/nightly/std/primitive.char.html)中找到更多關于`char`的文檔。
### 數字類型
Rust有一些分類的大量數字類型:有符號和無符號,定長和變長,浮點和整型。
這些類型包含兩部分:分類,和大小。例如,`u16`是一個擁有16位大小的無符號類型。更多字節讓你擁有更大的數字。
如果一個數字常量沒有推斷它類型的條件,它采用默認類型:
~~~
let x = 42; // x has type i32
let y = 1.0; // y has type f64
~~~
這里有一個不同數字類型的列表,以及它們在標注庫中的文檔:
- [i8](http://doc.rust-lang.org/nightly/std/primitive.i8.html)
- [i16](http://doc.rust-lang.org/nightly/std/primitive.i16.html)
- [i32](http://doc.rust-lang.org/nightly/std/primitive.i32.html)
- [i64](http://doc.rust-lang.org/nightly/std/primitive.i64.html)
- [u8](http://doc.rust-lang.org/nightly/std/primitive.u8.html)
- [u16](http://doc.rust-lang.org/nightly/std/primitive.u16.html)
- [u32](http://doc.rust-lang.org/nightly/std/primitive.u32.html)
- [u64](http://doc.rust-lang.org/nightly/std/primitive.u64.html)
- [isize](http://doc.rust-lang.org/nightly/std/primitive.isize.html)
- [usize](http://doc.rust-lang.org/nightly/std/primitive.usize.html)
- [f32](http://doc.rust-lang.org/nightly/std/primitive.f32.html)
- [f64](http://doc.rust-lang.org/nightly/std/primitive.f64.html)
讓我們按分類重溫一遍:
### 有符號和無符號
整型有兩種變體:有符號和無符號。為了理解它們的區別,讓我們考慮一個 4 比特大小的數字。一個有符號,4 比特數字你可以儲存`-8`到`+7`的數字。有符號數采用“補碼”表示。一個無符號 4 比特的數字,因為它不需要儲存負數,可以出儲存`0`到`+15`的數字。
### 固定大小類型
固定大小類型在其表現中有特定數量的位。有效的位大小是`8`,`16`,`32`和`64`。那么,`u32`是無符號的,32 位整型,而`i64`是有符號,64 位整型。
### 可變大小類型
Rust 也提供了依賴底層機器指針大小的類型。這些類型擁有“size”分類,并有有符號和無符號變體。它有兩個類型:`isize`和`usize`。
### 浮點類型
Rust 也有兩個浮點類型:`f32`和`f64`。它們對應 IEEE-754 單精度和雙精度浮點數。
### 數組
像很多編程語言一樣,Rust有用來表示數據序列的列表類型。最基本的是*數組*,一個定長相同類型的元素列表。數組默認是不可變的。
~~~
let a = [1, 2, 3]; // a: [i32; 3]
let mut m = [1, 2, 3]; // m: [i32; 3]
~~~
數組的類型是`[T; N]`。我們會在[泛型部分](#)的時候討論這個`T`標記。`N`是一個編譯時常量,代表數組的長度。
有一個可以將數組中每一個元素初始化為相同值的簡寫。在這個例子中,`a`的每個元素都被初始化為`0`:
~~~
let a = [0; 20]; // a: [i32; 20]
~~~
你可以用`a.len()`來獲取數組`a`的元素數量:
~~~
let a = [1, 2, 3];
println!("a has {} elements", a.len());
~~~
你可以用*下標*(*subscript notation*)來訪問特定的元素:
~~~
let names = ["Graydon", "Brian", "Niko"]; // names: [&str; 3]
println!("The second name is: {}", names[1]);
~~~
就跟大部分編程語言一個樣,下標從0開始,所以第一個元素是`names[0]`,第二個是`names[1]`。上面的例子會打印出`The second name is: Brian`。如果你嘗試使用一個不在數組中的下標,你會得到一個錯誤:數組訪問會在運行時進行邊界檢查。這種不適當的訪問時其它系統編程語言中很多bug的根源。
你可以在[標準庫文檔](http://doc.rust-lang.org/stable/std/primitive.array.html)中找到更多關于`array`的文檔。
### 切片(Slices)
一個*切片*(*slice*)是一個數組的引用(或者“視圖”)。它有利于安全,有效的訪問數組的一部分而不用進行拷貝。比如,你可能只想要引用讀入到內存的文件中的一行。原理上,片段并不是直接創建的,而是引用一個已經存在的變量。片段有預定義的長度,可以是可變也可以是不可變的。
### 切片語法
你可以用一個`&`和`[]`的組合從多種數據類型創建一個切片。`&`表明切片類似于[引用](#),這個我們會在本部分的后面詳細介紹。帶有一個范圍的`[]`,允許你定義切片的長度:
~~~
let a = [0, 1, 2, 3, 4];
let complete = &a[..]; // A slice containing all of the elements in a
let middle = &a[1..4]; // A slice of a: just the elements 1, 2, and 3
~~~
片段擁有`&[T]`類型。當我們涉及到[泛型](#)時會討論這個`T`。
你可以在[標準庫文檔](http://doc.rust-lang.org/stable/std/primitive.slice.html)中找到更多關于`slices`的文檔。
### `str`
Rust的`str`類型是最原始的字符串類型。作為一個[不定長類型](#),它本身并不是非常有用,不過當它用在引用后是就有用了,例如[&str](#)。如你所見,我們到時候再講。
你可以在[標準庫文檔](http://doc.rust-lang.org/stable/std/primitive.str.html)中找到更多關于`str`的文檔。
### 元組(Tuples)
元組(tuples)是固定大小的有序列表。如下:
~~~
let x = (1, "hello");
~~~
這是一個長度為2的元組,有括號和逗號組成。下面也是同樣的元組,不過注明了數據類型:
~~~
let x: (i32, &str) = (1, "hello");
~~~
如你所見,元組的類型跟元組看起來很像,只不過類型取代的值的位置。細心的讀者可能會注意到元組是異質的:這個元組中有一個`i32`和一個`&str`。在系統編程語言中,字符串要比其它語言中來的復雜。現在,可以認為`&str`是一個*字符串片段*(*string slice*),我們馬上會講到它。
你可以把一個元組賦值給另一個,如果它們包含相同的類型和[數量](#)。當元組有相同的長度時它們有相同的數量。
~~~
let mut x = (1, 2); // x: (i32, i32)
let y = (2, 3); // y: (i32, i32)
x = y;
~~~
你可以通過一個*解構let*(*destructuring let*)訪問元組中的字段。下面是一個例子:
~~~
let (x, y, z) = (1, 2, 3);
println!("x is {}", x);
~~~
還記得[之前](#)我曾經說過`let`語句的左側遠比一個賦值綁定強大嗎?這就是證據。我們可以在`let`左側寫一個模式,如果它能匹配右側的話,我們可以一次寫多個綁定。這種情況下,`let`“解構”或“拆開”了元組,并分成了三個綁定。
這個模式是很強大的,我們后面會經常看到它。
你可以一個逗號來消除一個單元素元組和一個括號中的值的歧義:
~~~
(0,); // single-element tuple
(0); // zero in parentheses
~~~
### 元組索引(Tuple Indexing)
你也可以用索引語法訪問一個元組的字段:
~~~
let tuple = (1, 2, 3);
let x = tuple.0;
let y = tuple.1;
let z = tuple.2;
println!("x is {}", x);
~~~
就像數組索引,它從`0`開始,不過也不像數組索引,它使用`.`,而不是`[]`。
你可以在[標準庫文檔](http://doc.rust-lang.org/stable/std/primitive.tuple.html)中找到更多關于`tuple`的文檔。
### 函數
函數也有一個類型!它們看起來像這樣:
~~~
fn foo(x: i32) -> i32 { x }
let x: fn(i32) -> i32 = foo;
~~~
在這個例子中,`x`是一個“函數指針”,指向一個獲取一個`i32`參數并返回一個`i32`值的函數。
- 前言
- 貢獻者
- 1.介紹
- 2.準備
- 3.學習 Rust
- 3.1.猜猜看
- 3.2.哲學家就餐問題
- 3.3.其它語言中的 Rust
- 4.語法和語義
- 4.1.變量綁定
- 4.2.函數
- 4.3.原生類型
- 4.4.注釋
- 4.5.If語句
- 4.6.循環
- 4.7.所有權
- 4.8.引用和借用
- 4.9.生命周期
- 4.10.可變性
- 4.11.結構體
- 4.12.枚舉
- 4.13.匹配
- 4.14.模式
- 4.15.方法語法
- 4.16.Vectors
- 4.17.字符串
- 4.18.泛型
- 4.19.Traits
- 4.20.Drop
- 4.21.if let
- 4.22.trait 對象
- 4.23.閉包
- 4.24.通用函數調用語法
- 4.25.crate 和模塊
- 4.26.const和static
- 4.27.屬性
- 4.28.type別名
- 4.29.類型轉換
- 4.30.關聯類型
- 4.31.不定長類型
- 4.32.運算符和重載
- 4.33.Deref強制多態
- 4.34.宏
- 4.35.裸指針
- 4.36.不安全代碼
- 5.高效 Rust
- 5.1.棧和堆
- 5.2.測試
- 5.3.條件編譯
- 5.4.文檔
- 5.5.迭代器
- 5.6.并發
- 5.7.錯誤處理
- 5.8.選擇你的保證
- 5.9.外部函數接口
- 5.10.Borrow 和 AsRef
- 5.11.發布途徑
- 5.12.不使用標準庫
- 6.Rust 開發版
- 6.1.編譯器插件
- 6.2.內聯匯編
- 6.4.固有功能
- 6.5.語言項
- 6.6.鏈接進階
- 6.7.基準測試
- 6.8.裝箱語法和模式
- 6.9.切片模式
- 6.10.關聯常量
- 6.11.自定義內存分配器
- 7.詞匯表
- 8.語法索引
- 9.參考文獻
- 附錄:名詞中英文對照