基础类型

rust是一门静态编程语言, 所以我们有必要知道它的类型, rust的类型可以分为基本类型和复合类型(也可以称之为复杂类型), 基本类型指的就是原子化最小的类型, 它不能转换为其他类型;

rust不像ts, ts是js的超集, ts可以更好的推断类型, 但是rust拥有一个很聪明的编译器, 你可以无需指定类型, 让编译器去自动推断, 但是某些情况下编译器无法推断类型, 比如这样

let guess = "42".parse().expect("Not a number!");

鬼知道guess是什么类型, 所以编译器会报错, 你只需要显式的指定类型即可;

数值类型

rust创建数值非常简单

let a = 1;

整数

我们继续来探讨整数类型, 我们之前了解过的i32类型, 表示有符号的32位整数

i表示integer, 与之相反的是u, 代表无符号

类型统一定义为 “有无符号” + “位数(bit)”, 无符号表示就是正数, 有符号就是正负; 简单的使用准则需要我们记住, rust整形默认使用i32, 可以首选i32, 而且性能也是最好的;

我们在处理整型的时候, 如果设置的值超过了范围, 那么rust会区分模式, 做不同的决策, 比如在debug模式中, 程序会报错退出; 如果是release环境, 会被补码为范围内的最小值, 因此这样的结果是不符合预期的, 会被认为是错误的.

浮点数

浮点数默认类型是f64, 但是rust有一个浮点数的陷阱, 我们通常会使用十进制表达浮点数, 但是rust底层是使用二进制实现浮点数类型的, 比如说0.5在十进制上存在精确表达, 但是在二进制中不存在, 所以就会造成歧义, 所以想要表达完整的真实浮点数字, 就必须使用无限精度的浮点数才行.

还有一个注意的点就是, 我们不要对浮点进行比较, 这和js一样, 由于rust的浮点类型底层是二进制, 而js同样在浮点数运算时也是二进制, 都会存在不准确的问题; 在rust中对浮点数进行比较的时候, float声明了PartialEq, 注意它不是Eq; 在map数据结构中的k类型, rust是需要你传入声明过Eq 的类型, 很显然float不满足要求; 而且当我们使用浮点做比较的时候, 会造成编译器错误.

NaN

和js一样, 我们可以在rust中做一个防御性编程:

fn main() {
    let x = (-42.0_f32).sqrt();
    if x.is_nan() {
        println!("未定义的数学行为")
    }
}

序列

rust提供了一种简洁的方式生成连续的数值

// 生成1-5 (包括5)
1..=5
// 生成1-5 (不包括5)
1..5

字符, 布尔, 单元类型

这一部分比较简单,

char

fn main() {
    let c = 'z';
    let z = 'ℤ';
    let g = '国';
    let heart_eyed_cat = 'hhh';
}

不管是ascii, 还是unicloud都算作rust字符char; 另外字符是用’’包裹的, “”是表达为字符串

bool

rust中的布尔类型和其他语言一样, 存在true/false

单元类型

0长度的元组, 单元类型使用()来表达, 我们可以用单元类型占位, 它不占用任何内存, rust函数中的main还有print函数都会返回一个单元类型. 我们不能说main函数没有返回值, 因为没有返回值在rust中是有单独的定义的(发散函数: diverge function) , 顾名思义, 无法收敛的函数.

语句和表达式

在rust的函数体中是一系列语句组成, 最后是由表达式返回, 比如这样

fn add(x: i32, y: i32) -> i32 {
    let x = x + 2; // 语句
    let y = y + 3; // 语句
    x + y // 表达式
}

语句

 let x = x + 2; // 语句
 let y = y + 3; // 语句

由于let是语句, 我们不能将let赋值给其他值:

let b = (let a = 8);

这样编译器会报错…

表达式

表达式会进行运算/求值, 比如1+2, 会返回3, 我们在语句上面写了这段代码:

 let x = x + 2; 

这里的x + 2确实是一个表达式, 只要记住只要能返回值, 它就是表达式 而且表达式不能包含分号, 比如下面一段代码

let y = {
    let x = 3;
    x + 1
};

如果x + 1包含了分号, 那么此时这个语句块不会返回任何值了, 也就不算作表达式了, 所以我们在rust中编写函数的时候, 如果要返回值, 就要注意这里不需要加分号;

函数

rust的函数很简单, 下面是一个例子, 有关键字, 函数名称, 形参名称和类型, 函数返回值类型, 以及一个代码块, 就构成了一个最简单的函数:

fn add(i: i32, j: i32) -> i32 {
   i + j
 }
  1. 首先rust是强类型的语言, 我们在编写函数的时候, 参数的类型是必须的, 如果不提供参数的类型是会报错的.
  2. 函数的返回值就是代码块的最后一行的表达式返回值, 当然我们也可以使用return关键字提前返回也可以
  3. 在单元类型中, 我们提到了无返回值, 我们可以使用单元类型作为返回, 而一些表达式你不幸加了分号变成了语句, 那么此时也会返回一个单元类型.
  4. 在上文提到了diverge function, 我们可以使用!作为函数返回类型, 这一般会作为程序崩溃的函数, 代表永不返回:
fn end() -> ! {
  panic!("it is over...");
}

标签: none

添加新评论