5分钟速读之Rust权威指南(二)

427 阅读4分钟

数据类型

这一节来介绍rust的数据类型,在JS中有string、number、boolean、symbol、null、undefined、object,拿number类型来说,rust中包含多种数字类型。另外,如果用过TS的话可能会听说过tuple元组类型,rust中也存在元组。

标量类型(scalar)标量就是基础类型,包含整数、浮点数、布尔、字符串

整数,包含i和u系列

长度有符号无符号
8位i8u8
16位i16u16
32位i32u32
64位i64u64
设备架构isizeusize
  • 对于i8来讲,范围是-2的7次方→2的七次方减1,也就是-128→127
  • 对于u8来讲,范围是2的8次方减1,也就是-128→127
  • 对于in来讲,范围就是-2的(n-1)次方→2的(n-1)次方减1
  • 对于un来讲,范围就是2的n次方减1
  • isize和usize:它们的长度取决于程序运行的目标平台。在64位架构上,它们就是64位的,而在32位架构上,它们就是32位的。
  • 字面量声明
// rust会自动将类型推断为i32
let a = 20;

// 显式声明
let b: i32 = 20;

// 字面量方式,在数字后面跟一个类型
let c = -20i8;
let d = 20u8;

// 可以使用分隔符提升易读性
let e = 1_000u16;

// 字面量16进制
let f = 0xff;
// 255

// 字面量八进制
let g = 0o77;
// 63

// 字面量二进制
let h = 0b111_0000;
// 112

// 单个字符的ASCII值,得到一个u8类型
let l = b'a'
// 97

新手入门的话,我们一般使用i32就够了,它的运算速度大部分情况也是速度最快的一个。

浮点数 f系列

  • f32,占用32位长度
let a = 0.2f32;
  • f64,占用64长度
// 默认就是f64,两者等价
let a = 0.2;
let a2 = 0.2f64;

// rust也使用的IEEE754标准,存在失真问题: 
0.1 + 0.2;
// 0.30000000000000004

布尔 bool

与JS一样,只有两个布尔值

// 自动推断
let c = true;
// 显式注明类型
let d: bool = false;

字符 char

单个字符(char)使用单引号定义

// 只能是单个字符
let e = 'e';

// 多个字符会报错 error
let e2: char = 'e2';

// 不存在空字符串 error
let empty: char = '';

// 单个字符可以是emoji
let e3 = '🍔';

rust中的char类型占4字节,是一个Unicode标量值,这也意味着它可以表示比ASCII多得多的字符内容。

拼音字母、中文、日文、韩文、零长度空白字符,甚至是emoji表情都可以作为一个有效的char类型值。

实际上,Unicode标量可以描述从U+0000到U+D7FF以及从U+E000到U+10FFFF范围内的所有值。

由于Unicode中没有“字符”的概念,所以你现在从直觉上认为的“字符”也许与rust中的概念并不相符。

多个字符可以组成一个字符串(str)

// str
let s = "string";

// 显式指定类型 &str,这里的&表示引用,可以先忽略,后面章节会介绍到
let s2: &str = "string";

复合类型 compound

数组 array

用方括号创建数组,成员类型必须一致,数组长度不可变,动态长度数组可以用vector类型(后面章节会有介绍)

// 声明类型同样会自动推断,或使用方括号,将类型与长度用分号分隔开
let i: [i32; 3] = [1, 2, 3];

// 不能存在不同的类型,会报错
let i2 = [1,2,3, ' ', true];

// 用方括号取值、用len()方法获取长度
println!("{}-{}", i[0], i.len())

// 简洁声明:[填充;长度]
let m = [2;3];
// 相当于
let m2 = [2, 2, 2];
println!("{}-{}-{}", m[0], m[1], m[2])
// 2-2-2

// 访问数组超出范围会报错
let n = [1;3]
println!("{}", n[3])

// 解构方式取值
let [o, p] = n;
println!("{}-{}", o, p)

元组 tuple

用圆括号来声明元组,如果不指定类型,编译器会自动推断

// 定义元组,分别标注每一个成员的类型
let tup2: (i32, char, bool) = (1, 's', true);

// rust也支持自动推断类型
let tup = (1, 's', true);

// 通过结构对元组进行取值
let (f, g, h) = tup;
println!("{}-{}-{}", f, g, h)
 // 1 s true

// 通过索引来访问
println!("{}-{}-{}", tup.0, tup.1, tup.2)
 // 1 s true

// 元组没有len()方法,调用会报错
tup.len()

好奇的同学可能会问为什么没有出现object类型,也就是JS中的对象,事实上rust中类似JS中对象的东西叫做结构体struct,由于结构体稍微比较复杂,后面会有单独的章节介绍。