Rust(待更新)


序章

前言

发生了很多我意料之外的事情,我也因此感慨万分

虽然其中的道理我早有耳闻,但是切身体会后内心还是会泛起伤感

在此之后我不免对开源产生了怀疑——我为什么要开源?

这是我之后需要思考的问题,而现在则是认真地学习Rust

更新日志

2022/02/20
这次准备对官方文档做摘要了

概述

发展

特性

Rust 语言为了高并发安全而做的设计

基础语法

变量和常量

按照做摘要的原则,我会过滤掉那些过于简单和相对熟悉的内容,但是Rust的变量实在是太特别了

不可变变量

Rust是强数据类型语言,但是能够做自动类型判断,变量声明语法如下:

let a = 123;

再执行上述语句后,下面这些代码将会报错

a = "abc"; // 类型发生了转变
a = 4.56;  // 精度发生了损失
a = 456;   // Rust的奇妙特性

重点解释第三种情况——要知道a是一个变量,要是不能改变那不就是常量了吗?
a 的值不可变。但这不意味着 a 不是”变量”(英文中的 variable),官方文档称 a 这种变量为**”不可变变量”**(就离谱)

这就牵扯到了 Rust 语言为了高并发安全而做的设计:在语言层面尽量少的让变量的值可以改变

但是以下代码是合法的

let a = 123;
let a = 456;

这样相当于“重新绑定”了,这也是不可变量和常量的区别

当然,”重新绑定”只能改变值而不能改变数据类型

这里的”重新绑定”严格来说是指的重影,这个概念后面再提

可变变量

当然,上面这种机制在很多情况下会比较难受,所以还是需要我们熟悉的正常变量

let mut a = 123;
a = 456;

常量

语法如下:

const a = 123; // 有符号三十二位

数据类型

只讨论较为特殊的

虽然能自动判别数据类型,但是依旧是可以指定数据类型,语法类似TS

let a: u64 = 123;	// 无符号64位
const a: i32 = 123;  // 有符号32位

如果不指定类型,那么对于数字声明来说默认是有符号32位

整数型

Integer,简称整形,按照比特长度和有无负号分类

位长度 有符号 无符号
8-bit i8 u8
16-bit i16 u16
32-bit i32 u32
64-bit i64 u64
128-bit i128 u128
arch isize usize

isize 和 usize 两种整数类型是用来衡量数据大小的,它们的位长度取决于所运行的目标平台,如果是 32 位架构的处理器将使用 32 位位长度整型。

进制
十进制 98_222
十六进制 0xff
八进制 0o77
二进制 0b1111_0000
字节(只能表示 u8 型) b’A’

浮点数型

Floating - Point,

只需要记住有32位和64位,默认是64位即可

fn main() {
    let x = 2.0; // f64
    let y: f32 = 3.0; // f32
}

字符型

char,但是与C/C++不同的是,rust的char是4个字节,代表Unicode标量值,这意味着中文日文甚至是emoji表情符号在rust中都是有效的字符

当然,有时候我们对字符的认识可能会和rust不一致,并且由于现行的中文编码有GBK和UTF-8两套,所以中文仍可能会出现乱码

为了尽可能规避乱码,UTF-8字符尽可能使用字符串存储

数组

大体上和JS类似,主要是看一段示例:

let b = ["January", "February", "March"];
// b 是一个长度为 3 的字符串数组

let c: [i32; 5] = [1, 2, 3, 4, 5];
// c 是一个长度为 5 的 i32 数组

let d = [3; 5];
// 等同于 let d = [3, 3, 3, 3, 3];

let first = a[0];
let second = a[1];
// 数组访问

a[0] = 123; // 错误:数组 a 不可变
let mut a = [1, 2, 3];
a[0] = 4; // 正确

复合类型

元组用一对()包括一组数据,可以包含不同类型的数据

这里和ES6中的解构赋值类似之处

let tup: (i32, f64, u8) = (500, 6.4, 1);
// tup.0 等于 500
// tup.1 等于 6.4
// tup.2 等于 1
let (x, y, z) = tup;
// y 等于 6.4

重影

重影的概念与其他面向对象语言里的”重写”(Override)或”重载”(Overload)是不一样的。重影就是刚才讲述的所谓”重新绑定”,之所以加引号就是为了在没有介绍这个概念的时候代替一下概念

fn main() {
    let x = 5;
    let x = x + 1;
    let x = x * 2;
    println!("The value of x is: {}", x);
}

运行结果

The value of x is: 12

重影是指用同一个名字重新代表另一个变量实体,其类型、可变属性和值都可以变化。但可变变量赋值仅能发生值的变化,数据类型是不允许变化的!

注释

rust有常规的两种注释形式,还有非常特殊的第三种注释:

/// Adds one to the number given.
///
/// # Examples
///
/// ```
/// let x = add(1, 2);
///
/// ```

这样的注释支持markdown语法,是作为说明文档注释的开头

能达到下面这样的效果,非常惊艳!

函数

主函数

和C/C++类似,rust需要一个主函数,其基本格式如下:

fn main () {
    println!("Hello World!");
}

没有参数,也没有返回值!

自定义函数

基本使用

和JS一样,函数声明自动提升,所以不必在意调用和声明的先后顺序

但是需要注意,rust中声明函数需要指定类型,语法类似TS

fn another_function(x: i32, y: i32) {
    println!("x 的值为 : {}", x);
    println!("y 的值为 : {}", y);
}

函数体表达式

大概是个语法糖

fn main() {
    let x = 5;

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

    println!("x 的值为 : {}", x);
    println!("y 的值为 : {}", y);
}

最后输出的结果是:

x 的值为 : 5
y 的值为 : 4

没错,不仅没有输出花括号,而且y的值是4

没有输出花括号是因为rust中的花括号可以理解为c中的%d%c%s等等

可以将函数的形式简写成上述代码中的那样,其中最后一句必须是表达式 且 不加分号,作为返回值(最后一行加上分号则会变成一条语句)

而且如果要使用这种简写,那么一定要放到最后一行!!

当然,return是随时都可以使用

返回值类型声明

如果要限定返回值的类型,那么就可以使用如下形式:

fn add(a: i32, b: i32) -> i32 {
    return a + b;
}

在->后加上返回值类型即可声明

条件语句

如果是耳熟能详的内容,那我绝不会在这里大费周章

基本使用

和python类似,这里不再需要括号(但是依然可以写,因为括号可以看做表达式的一部分)

而且条件表达式必须是bool类型

if a > 0 {
    b = 1;
}  
else if a < 0 {
    b = -1;
}  
else {
    b = 0;
}

由于rust是注重安全的,所以非0即true这种自动类型转换时不被允许的

结合函数体表达式

这样的效果和三目运算差不多

let number = if a > 0 { 1 } else { -1 };

两个函数体表达式的类型必须一样!且必须有一个 else 及其后的表达式块

(因为赋值操作的等号右边必须要有一个返回值)

循环

while循环

while只提两点:

  1. 不需要括号
  2. 暂时没有do-while,do作为了保留字

for循环

没有像C那样的三元语句控制循环,而是用迭代器的形式遍历

for i in a.iter() {
    println!("值为 : {}", i);
}

当然还可以通过下标来访问:

fn main() {
let a = [10, 20, 30, 40, 50];
    for i in 0..5 {
        println!("a[{}] = {}", i, a[i]);
    }
}

看上去有点粗陋就是了额

loop循环

这个相当于加强版的while(true){}

let s = ['R', 'U', 'N', 'O', 'O', 'B'];
let mut i = 0;
let location = loop { // 没错loop循环有一个类似返回值的操作
    let ch = s[i];
    if ch == 'O' {
        break i;	// 可以通过break做到类似返回值的效果
    }
    i += 1;
};

文章作者: Serio
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Serio !
  目录