通过各方面学习了解到了Rust这个语言.
Rust学习之为什么有Rust
1. 解决什么问题
首先有GC(垃圾回收)的语言性能不够极致, 而无GC差不多就只有C与C++, 可这两个语言在运行阶段容易出现空指针或野指针的情况, 并且无法在编译期间就检查出来.
综上, 那么Rust需要解决的就是无GC+无空指针:
2. 无GC好办:
为啥有GC, 我们的程序运行时会有栈与堆, 栈是存放函数与变量的, 堆是用来存放大型变量或可变变量的. 而由于我们存放在栈里的资源较小, 当我们共享变量时, 直接复制一份即可; 可堆中的变量极大, 复制一份性能消耗大. 因此我们采用指针指向同一份堆资源的方式来实现共享变量, 可如果多个指针指向同一份堆变量时, 我们应该如何确定什么时候这个变量应该被释放.
首先最容易想到的, 就是当最后一个指针取消指向时, 这个时候就释放资源, 可是则便是GC的一个原理, 也即有一个程序定时的去检查有无栈中的指针指向堆中的变量, 如果没有则释放.
那既然则时机不好把握, 而我们又必须实现变量共享(没有变量共享的编程语言没意义); 于是我们可以设定, 当有新的指针指向时(一般是原来的指针赋值给新的指针), 这个时候我们便认为"所有权“发生了转移, 也即原来的指针失效, 以新指针为准, 而当我们的指针离开作用域时便释放资源.
可是这样的话, 如果我们需要在不同作用域传参时, 不就马上失效了吗? 因此我们引入了”借用"(其实就是引用), 也即用堆上的空间指向我们当前拥有所有权的堆指针, 如此一来由于该借用并不直接指向堆空间, 因此不会释放堆资源.
但是, 如果我们多个借用都可以修改堆空间的话, 就像同时读写一样, 会导致内存污染. 因此我们设定了"可变借用“与”不可变借用", 可变借用也即写锁, 同一时刻只能有一个可变借用, 同时有了可变借用也不能有不可变借用; 如果是不可变借用, 则可同时有多个不可变借用.
到目前为止也就实现了"无GC".
3. 接下来就是空指针问题:
对于这个问题, 我们引入"生命周期", 也即, 我们的借用的生命周期, 不能长于原始借用对象的生命周期; 这一点编译器会替我们检查, 不过有些情况编译器无法智能识辨, 例如我传入多个借用, 让后依据一些条件返回不同的借用, 这个时候, 编译器并不知道函数逻辑, 他只知道返回的一个与传入的两个有关, 但是到底怎么相关, 编译器不知道, 因此需要我们手动标注. (离开作用域, 则生命周期结束)
4. 总结
对于上面这些初学概念, 我认为上手rust最难的应该是"生命周期", 不过我认为目前可以先写函数然后通过与哪些有关联的方式来标注, 亦或是直接让ai助手根据上下文帮我们标注.
5. 特别补充
rust中有String, &str, 和&String:
String很好理解可变字符串, 在栈上占用24字节, 分别存放堆地址指针, 容量, 长度.&String也很好理解, 在栈上占用8字节, 存放指向的String栈地址.&str得好好理解, 可理解为不可变数组, 在栈上占用16字节, 分别存放堆地址指针和长度.
当变量拥有借用时, 且借用生命周期未结束, 则无法转移所有权:
|
|
当变量拥有不可变借用时, 且未失效时, 原有所有权的变量也无法更改(被冻结了):
|
|
当变量拥有可变借用时, 且未失效时, 原有所有权的变量既无法读也无法写:
|
|
有了可变借用, 就不能有不可变借用, 反之亦然, 可变不会降级为不可变:
|
|