初识 Rust




数值计算和线程方面优势
有类型推导
没有并发限制 // 一些语言为了安全限制了并发 GIL(全局解释器锁)
没有实质的运行时,支持 FFI(外部函数调用,静态链接库/动态链接库),也可以简单的在 C 中被调用
基于表达式的语言

作为一种编程语言基础的是 Primitive Types + Keywords + Operators and Symbols, Rust 还内建了一些 crate,如 std,alloc,core,proc_macro,test
std 中包含许多 Modules(prelude, thread, process...),Macros(assert, print... 使用时全部不需要手动引入)
prelude 的内容被预加载,使用时不需要再引入

函数调用提供的数据要么被 Copy 要么所有权发生转移(之后不能用了)
= 默认是移动,实现 Copy trait 才会像 js 原始值一样复制
函数的最后表达式(没有分号,有分号是语句)是自动返回的
std 库使用下划线连接
as 转类型或标记类型 // 例如 `self as &dyn error::Error`
let v: &mut i32 = Box::new(0).as_mut(); // 转化引用
Rust 中有两种类型的语句:"声明语句"和"表达式语句"。其余的一切是表达式
函数没有返回值可以省略整个返回值类型
let 创建变量绑定,默认不可变,使用 mut 让其可变,赋值符号左边接受一个模式(解构)
let 可以重复创建相同名称并且覆盖
const 表示一个常量,不能使用 mut,变量名常使用蛇形全大写 // 每个使用的地方编译时被替换
const generics 使用常量的地方也可以通过范型来标记 // 例如数组类型 [i32; usize] 中的 usize
usize 整数类型,其长度取决于平台
static 定义具有 'static 生命周期的常量,必须写类型,只有一个实例,和 const 不同的是不会被内联
& 表示引用,默认引用不可变,使用 &mut guess // guess 是可变变量绑定
* 解引用,访问引用的原值
ref 绑定(模式匹配中)引用值 // let ref ref_value = 3
*const T, and *mut T 原始指针
String 是一个字符串类型,是 char 的集合。String 是一个可增长的,UTF-8 编码的文本 // js 字符不可变
&str 类型是另一个字符串的引用,to_string 方法返回字符串的一份拷贝 // 指向一个字符串切片
"" 字符串字面值,是 slice,是一个不可变引用,可以写多行
r#""# 原始字符串,不需要转义 // r#try()
format! 格式化字符串 // 使用 {{}} 表示 {}
'' char 类型,代表的是一个 Unicode 标量值 // 四个字节
数字字母量默认 i32 / f64
use std::io; 相当于在 js 中定义常量 io = std.io
extern crate rand; 导入外部库
pub extern // 导出为外部库
.. 表示范围,..= 包含结尾 // 在结构体中可以用作展开符
pub use // 导出嵌套的公有 API
trait // 像 interface
impl TraitName // Trait 作为参数的类型注解,作为范型的约束时称为 Trait bounds,通过 where 简化代码
dyn Trait // 类型标注中用来替代原来的 Trait,如返回空间不确定的类型 Box
=> 箭头函数 // -> 指定函数返回类型
unwrap // 不捕捉 None
match 类似 js 中的 switch ,但不需要 break ,写法也不一样 // 能匹配单值多值,不能写条件
expect 方法捕捉错误
? // 错误传播,与 try! 相同
关联类型:实现 trait必须同时指定的类型 // 不同于类型别名
虚类型(phantom type):在运行时不出现,仅在编译时进行静态检查的类型参数,例子
函数的参数上模式匹配:fn my_func(Fubarize(fub): Fubarize) // struct
.await // async 函数中执行异步函数

if let 是一种模式,匹配 Some // if let Some(n) = last {}
@ 模式中绑定到变量
_ 不能作为变量名,是一个占位符,也可用于数字中(比如千分位)
Vec<_> // 向量类型,元素是 ** 类型
struct 定义数据结构 // 类似 js 对象
tuple 使用数字 key 的 struct
HashMap 可变长度的 struct
使用结构名直接生成一个实例:Philosopher { name: "Judith Butler".to_string() };
impl StuctName 块中来定义方法 // impl TraitName for StuctName
::new() 语法用了 :: 因为它是一个特定类型的"关联函数" // 首个参数不是 self ,相当于js静态方法
"42".parse::() // turbofish 调用是显式指定范型类型
使用 &self 显式获取 self 参数,没有使用的即为静态方法 // Self 当前对象的类型
vec![] 生成长度可变向量
[] 长度不可变数组 // 带类型标记的速写:[2f32; 10]
.map(|p| { // 闭包
}).collect(); // 收集 map 产生的结果
thread::spawn(move || { // 移交所有权,返回线程句柄 || 是指闭包,函数中的内容运行在新线程中
线程句柄上调用 join(),会阻塞程序直到线程完成执行才退出程序
函数定义上行加注释 :#[no_mangle] 表明编译时不修改名字,是其他语言中调用的必要条件