写点什么

Rust 从 0 到 1- 基础概念 - 数据类型

用户头像
关注
发布于: 2021 年 03 月 25 日
Rust从0到1-基础概念-数据类型

看到 Rust 声明变量并不需要声明数据类型,还误以为是弱类型的语言(感觉这个不符合 Rust 的 Style),但实际上 Rust 是强类型的,官方的说法叫静态类型语言。譬如,如果未声明类型,会在第一次赋值的时候确定类型。

    这部分将介绍 Rust 两类基本数据类型,即标量类型和复合类型(和 C 类似,Java 里一般按照基本类型和引用类型分)。Rust 需要在编译时就确定数据类型,否则编译器会跳出来提醒你,来看下官方的例子:  

  let guess = "12".parse().expect("Not a number!");
复制代码

这个在编译时就会报错,因为编译器无法确定变量 guess 的类型。

标量类型

标量类型只能表示一个值。Rust 的标量类型主要有 4 个:整型、浮点型、布尔型、字符型。

整型

参见下表:

长度 |有符号|无符号|Java

8-bit | i8 | u8 | byte

16-bit | i16 | u16 | short

32-bit | i32 | u32 | int

64-bit | i64 | u64 | long

128-bit | i128 | u128 |

arch | isize | usize |

特别说明下 isize 和 usize 两个类型,这个类型是根据运行的目标操作系统环境决定,譬如,64 位的操作系统就是 64 位。Rust 的默认数据类型是 i32,这个类型在性能上一般是最快的,即使在 64 位的环境下。

Rust 的整型可以使用多种语法表示,默认都是 i32 ,但可以通过在后面增加后缀来指定类型(除了字节固定为 u8 ),譬如 255i16,参见下表:

十进制 | 10_000

十六进制 | 0xff

八进制 | 0o77

二进制 | 0b1111_0000

字节 | b'a'

其中 _ 是虚拟分隔符,类似于千分位分隔符,便于阅读。

    什么是有符号,什么是无符号以及不同位数所能表达的最大数字范围等这些基础知识就不介绍了。另外,补充说明下,Rust 对有符号数和数值溢出都是使用二补数(Two's complement)进行处理的,并且在编译时并不会提示你数值溢出了。

浮点型

Rust 浮点型主要包含单精度(f32)和双精度(f64)两个类型,默认为 f64 类型,这个在现代 CPU 上几乎和 f32 一样快,但是精度更高。浮点数的表示遵循 IEEE-754 标准,有兴趣的可以扩展阅读一下。

数值运算

Rust 支持基本的运算操作符,参考下面的例子:

fn main() {  // 加      let mut sum = 5 + 10;    sum += 15;  // 减  let mut difference = 15 - 10;  difference -= 5;  // 乘  let mut product = 2 * 2;  product *= 2;  // 除  let mut quotient = 8 / 2;  quotient /= 2;  // 求余  let mut remainder = 8 % 3;  remainder %= 2;}
复制代码
布尔型

Rust 布尔型只能有两个值,true 和 false ,大小是一个字节(1byte),参考下面的例子:

fn main() {  let good = true;  let good: bool = false; // with explicit type annotation}
复制代码
字符型

Rust 字符型是以 Unicode 表示,4 个字节大小,范围从 U+0000 到 U+D7FF 以及 U+E000 到 U+10FFFF(至于为什么跳过一段,这个也是 Unicode 标准中的规定)。需要注意的是字符型值是以单引号括起来,字符串才是使用双引号(这个与 C 类似),参加下面的例子:

fn main() {  let c = 'z';  let z = 'ℤ';  let heart_eyed_cat = '😻';}
复制代码

补充说明:我理解 Unicode 定义了“字符”对应的“数字”,UTF-8 定义了 Unicode 字符的编码方式,也就是存储或传输格式,感兴趣的可以扩展阅读下,编码问题也是编程中常见的问题之一。

复合类型

复合类型主要包含元组和数组两种类型。

元组类型

元组类型是一组值的集合,值的类型可以不同,并且长度是固定的,不能增加或减少。参考下面的例子:

fn main() {  let tup: (i32, f64, char) = (255, 3.14, 'A');  let tup = ('A', 3.14, 255);}
复制代码

同时元组类型的变量也可以很方便的展开,将每个值赋给不同的变量,参考下面的例子(变量前的下划线,意思是变量可能不被使用,避免编译器 warning):

fn main() {	let tup = (255, 3.14, 'A');  let (_v1, _v2, v3) = tup;  println!("The value of v3 is: {}", v3);}
复制代码

如果要直接访问元组类型里的值,也可以通过类似数值的下标访问,参考下面的例子:

fn main() {  let mut tup = (255, 3.14, 'A');  tup.2 = 'a';  println!("The value of v3 is: {}", tup.2);}
复制代码
数组类型

数组类型也是一组值的集合,但是和元组类型不同,值的类型必须是相同的;同时和 C、Java 等语言不同,数组类型和元组类型一样,长度都是固定的,不能增加或减少。参考下面的例子:

fn main() {  let a = [1, 2, 3, 4, 5];  let a: [i32; 5] = [1, 2, 3, 4, 5]; //声明数组中的数据类型和数量  let a = [3; 5];  //等于let a = [3, 3, 3, 3, 3];}
复制代码

数组类型里的值的访问和其它语言类似,可以通过下标访问,参考下面的例子:

fn main() {    let a = [1, 2, 3, 4, 5];    let first = a[0];    println!("The first value of array is: {}", first);    let last = a[5];    println!("The last value of array is: {}", last);
}
复制代码

上面的例子在编译时候会报错,因为发生了越界访问的错误(其它语言数组越界错误一般在运行时才会抛出)。


发布于: 2021 年 03 月 25 日阅读数: 10
用户头像

关注

还未添加个人签名 2021.03.23 加入

还未添加个人简介

评论

发布
暂无评论
Rust从0到1-基础概念-数据类型