新聞中心
大家好,我是站長(zhǎng) polarisxu。

創(chuàng)新新互聯(lián),憑借十余年的成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站經(jīng)驗(yàn),本著真心·誠(chéng)心服務(wù)的企業(yè)理念服務(wù)于成都中小企業(yè)設(shè)計(jì)網(wǎng)站有上1000+案例。做網(wǎng)站建設(shè),選創(chuàng)新互聯(lián)建站。
這是 Rust 勸退系列的第 4 個(gè)教程,探討 Rust 中的基本數(shù)據(jù)類型,或叫標(biāo)量類型(scalar type)。
Rust 和 Go 一樣,都是靜態(tài)類型語言,這表示每個(gè)變量的類型必須明確。和 Go 類似,大多數(shù)情況下,Rust 編譯器能夠推斷出某個(gè)值的類型,不需要我們顯示指定,寫起來有點(diǎn)類似于弱類型似語言。但有些情況下,必須明確告知編譯器我們使用什么類型,在 Rust 中,這叫 「類型注解」(type annotations)。
對(duì)于類型注解,看一個(gè)常見的例子:
- let guess = "42".parse().expect("Not a number!");
這是將字符串 "42" 轉(zhuǎn)為數(shù)字 42。在 Go 語言中,一般這么做:
- guess, err := strconv.Atoi("42")
- if err != nil {
- panic(err)
- }
但上面的 Rust 代碼會(huì)報(bào)錯(cuò):
- error[E0282]: type annotations needed
- --> src/main.rs:2:9
- |
- 2 | let guess = "42a".parse().expect("Not a number!");
- | ^^^^^^ consider giving `guess` a type
這和 Go 還是不太一樣。Go 中很多時(shí)候,數(shù)值類型會(huì)是 int。
為了修復(fù)這個(gè)問題,我們需要為 number 指定一個(gè)類型,比如 u32。
- let guess: u32 = "42".parse().expect("Not a number!");
吐槽:在 Rust 中,類型注解和 Go 中一樣,放在變量后面。但 Rust 中變量和類型直接非得加一個(gè)冒號(hào)(:),而且一般冒號(hào)緊跟著變量名(rustfmt 的建議)。不知道冒號(hào)有啥特殊需要?!
Rust 內(nèi)置如下基本數(shù)據(jù)類型:
- 整數(shù)類型
- 有符合整數(shù):i8、i16、i32、i64、i128、isize
- 無符號(hào)整數(shù):u8、u16、u32、u64、u128、usize
- 浮點(diǎn)類型:f32、f64
- 布爾型:bool
- 字符型:char
01 整數(shù)類型
將整數(shù)類型整理為一張表,如下:(用 Go 語言對(duì)應(yīng)的類型作對(duì)比)
| 長(zhǎng)度 | 有符號(hào) | 無符號(hào) | Go 有符號(hào) | Go 無符號(hào) |
|---|---|---|---|---|
| 8-bit | i8 | u8 | int8 | uint8 |
| 16-bit | i16 | u16 | int16 | uint16 |
| 32-bit | i32 | u32 | int32 | uint32 |
| 64-bit | i64 | u64 | int64 | uint64 |
| 128-bit | i128 | u128 | - | - |
| arch | isize | usize | int | uint |
吐槽:有時(shí)候 Rust 真的很節(jié)省,int、uint 直接省略為 i、u,function 省略為 fn。但有時(shí)候又很繁瑣(不簡(jiǎn)潔),比如前面說到的變量和類型之間的冒號(hào)。
這里用 u、i 的形式,也需要一段時(shí)間適應(yīng)。
兩點(diǎn)說明:
- Go 中沒有 128 位長(zhǎng)度的整數(shù)
- isize 和 usize 對(duì)應(yīng) Go 中的 int 和 uint,它們的長(zhǎng)度依賴運(yùn)行程序的計(jì)算機(jī)架構(gòu):64 位架構(gòu)上它們是 64 位的, 32 位架構(gòu)上它們是 32 位的
在 Go 中,整型變量默認(rèn)類型是 int,以下代碼可以證明這一點(diǎn):
- x := 32
- fmt.Printf("%T\n", i)
- // 輸出:int
那 Rust 中默認(rèn)是什么類型呢?
我想在 Rust 中找到一種辦法,打印變量類型,網(wǎng)上找到了這樣的辦法(有點(diǎn)挫):
- // 打印變量類型的函數(shù)。該函數(shù)看不懂先放著。
- fn print_type_of
(_: &T) { - println!("{}", std::any::type_name::
()) - }
- fn main() {
- let x = 32;
- print_type_of(&x);
- // 輸出:i32
- }
可見 Rust 中整型變量默認(rèn)類型是 i32(即使在 64 位機(jī)器上,也是 i32)。這一定程度上說明,在 Go 中,整數(shù)一般建議用 int 類型;而 Rust 中,一般建議用 i32 類型。(所以,為什么開頭的 parse 不能默認(rèn)推斷為 i32 類型呢?怕溢出?)
更智能的類型推斷
上文說 Rust 和 Go 一樣,支持類型推斷。不過 Rust 的推斷更智能,怎么個(gè)智能法?看下面的代碼:
- // 打印變量類型的函數(shù)
- fn print_type_of
(_: &T) { - println!("{}", std::any::type_name::
()) - }
- fn main() {
- let x = 32;
- let y: i8 = x;
- print_type_of(&x);
- print_type_of(&y)
- }
根據(jù)上面的講解,x 應(yīng)該是默認(rèn)類型:i32。但實(shí)際上,x 和 y 的類型都是 i8。也就是說,因?yàn)?x 的類型沒有顯示的指定(類型注解),Rust 編譯器會(huì)根據(jù)上下文(實(shí)際上是 let y: i8 = x 這句)推斷出 x 的類型應(yīng)該和 y 一致,即 i8。
在 Go 中,int8 和 int 是不會(huì)進(jìn)行隱式轉(zhuǎn)換的,Rust 也一樣,必須進(jìn)行顯示轉(zhuǎn)換。但 Rust 的智能類型推斷,可以讓開發(fā)者少寫類型轉(zhuǎn)換的代碼。
比如上面代碼,在 Go 語言中是行不通的:
- package main
- import (
- "fmt"
- )
- func main() {
- x := 32
- var y int8 = x
- fmt.Printf("%T\n", x)
- fmt.Printf("%T\n", y)
- }
會(huì)報(bào)錯(cuò):
- cannot use x (type int) as type int8 in assignment
也就是說,Go 中的類型推斷不會(huì)考慮上下文,因此沒有 Rust 智能。
因?yàn)榫幾g器的強(qiáng)大,VSCode 中(安裝 rust-analyzer)會(huì)有類型提示,這樣上面的 print_type_of 函數(shù)也不需要了。做了一個(gè)動(dòng)圖,注意上面 x 的類型變化:
此外,isize 和 usize 類型一般用作某些集合的索引,以后文章會(huì)看到。
關(guān)于各種類型的表示范圍我列出了,因?yàn)檫@個(gè)系列不是為無編程經(jīng)驗(yàn)的人準(zhǔn)備的。這個(gè)系列更多是為 Go 愛好者準(zhǔn)備的 Rust 教程,因此和 Go 一致的地方可能不會(huì)講。
02 浮點(diǎn)類型
和 Go 一樣,Rust 也有兩種浮點(diǎn)數(shù)類型:f32 和 f64,對(duì)應(yīng) Go 中的 float32 和 float64。和 Go 一樣,默認(rèn)類型是 f64,可以通過類型注解指定具體的浮點(diǎn)類型。
- let x = 2.0; // 默認(rèn)是 f64
一般地,整數(shù)類型和浮點(diǎn)類型都成為數(shù)值類型。
數(shù)值類型有一些共同的東西。比如都支持基本的數(shù)學(xué)運(yùn)算。此外,除了通過類型注解指定類型,數(shù)值類型還可以在字面值后面帶上類型后綴指定類型,比如:
- let x = 2.0f32; // f32 類型
- let y = 32i64; // i64 類型
03 布爾型
和 Go 語言一樣,Rust 中的布爾類型使用 bool 表示(咋沒用 b、bl 之類的縮寫呢?哈哈哈)。有兩個(gè)可能的值:true 和 false。
- fn main() {
- let t = true;
- let f: bool = false; // 顯式指定類型注解
- }
04 字符型
Rust 中的 char 表示字符類型,是 Rust 的基本類型,字面值由單引號(hào)指定。
- let a = 'a';
- let b = '中';
- let c = '????';
可見,Rust 中的 char 類型和 Go 中的 rune 一樣,表示的是 Unicode 碼點(diǎn),占 4 個(gè)字節(jié)。
因?yàn)?Rust 中的字符串很復(fù)雜,而且不是基本類型,因此留在以后講解。
05 小結(jié)
本文介紹了 Rust 中的四種基本數(shù)據(jù)類型:整型、浮點(diǎn)型、布爾型和字符型。其中,浮點(diǎn)型、布爾型和字符型分別對(duì)應(yīng) Go 中的浮點(diǎn)型、布爾型和 rune 類型,但整型,Go 和 Rust 有些許不一樣,上文已經(jīng)詳細(xì)介紹了。此外,Go 中復(fù)數(shù)也是基本數(shù)據(jù)類型:complex64 和 complex128,而 Rust 中沒有,復(fù)數(shù)通過第三方庫(kù)實(shí)現(xiàn),比如:https://crates.io/crates/easy_complex。
此外,你可能會(huì)說 Go 中還有一個(gè)基本類型:byte,而 Rust 沒有。其實(shí) Go 中的 byte 只是 uint8 的別名。另外,string 在 Go 中是基本數(shù)據(jù)類型,而在 Rust 中不是。
本文轉(zhuǎn)載自微信公眾號(hào)「polarisxu」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系polarisxu公眾號(hào)。
網(wǎng)站標(biāo)題:Rust勸退系列之基本數(shù)據(jù)類型
當(dāng)前路徑:http://m.5511xx.com/article/cdceooe.html


咨詢
建站咨詢
