DevilKing's blog

冷灯看剑,剑上几分功名?炉香无需计苍生,纵一穿烟逝,万丈云埋,孤阳还照古陵

0%

Learn Rust

原文链接

变量

变量默认是不可改变的。不过可变性也是非常有用的。变量只是默认不可变;正如在第二章所做的那样,你可以在变量名之前加 mut 来使其可变。除了允许改变值之外,mut 向读者表明了其他代码将会改变这个变量值的意图。

1
2
3
4
5
6
7
8
9
fn main() {
let x = 5;

let x = x + 1;

let x = x * 2;

println!("The value of x is: {}", x);
}

通过let来shadowing之前的变量。mut 与隐藏的另一个区别是,当再次使用 let 时,实际上创建了一个新变量,我们可以改变值的类型,但复用这个名字。

1
2
3
4
5
let x = if condition {
5
} else {
6
}

所有权(系统)是 Rust 最为与众不同的特性,它让 Rust 无需垃圾回收(garbage collector)即可保障内存安全

一些语言中具有垃圾回收机制,在程序运行时不断地寻找不再使用的内存;在另一些语言中,程序员必须亲自分配和释放内存。Rust 则选择了第三种方式:通过所有权系统管理内存,编译器在编译时会根据一系列的规则进行检查。在运行时,所有权系统的任何功能都不会减慢程序

堆和栈

栈中的所有数据都必须占用已知且固定的大小

在编译时大小未知或大小可能变化的数据,要改为存储在堆上

所有权规则:

  1. Rust 中的每一个值都有一个被称为其 所有者owner)的变量。
  2. 值有且只有一个所有者。
  3. 当所有者(变量)离开作用域,这个值将被丢弃。

浅拷贝shallow copy)和 深拷贝deep copy),那么拷贝指针、长度和容量而不拷贝数据可能听起来像浅拷贝。不过因为 Rust 同时使第一个变量无效了,这个操作被称为 移动move)和克隆(clone)

1
2
3
4
let s1 = String::from("hello");
let s2 = s1;

println!("{}, world!", s1);

上述代码error,禁止无效的引用

哪些类型可以浅拷贝

那么什么类型是 Copy 的呢?可以查看给定类型的文档来确认,不过作为一个通用的规则,任何简单标量值的组合可以是 Copy 的,不需要分配内存或某种形式资源的类型是 Copy 的。如下是一些 Copy 的类型:

  • 所有整数类型,比如 u32
  • 布尔类型,bool,它的值是 truefalse
  • 所有浮点数类型,比如 f64
  • 字符类型,char
  • 元组,当且仅当其包含的类型也都是 Copy 的时候。比如,(i32, i32)Copy 的,但 (i32, String) 就不是。

不变引用和可变引用

1
2
3
4
5
6
7
8
9
fn main() {
let mut s = String::from("hello");

change(&mut s);
}

fn change(some_string: &mut String) {
some_string.push_str(", world");
}

可变引用有一个很大的限制:在特定作用域中的特定数据有且只有一个可变引用

用大括号,标明作用域

关于作用域部分,有很大的技巧,也就是声明和使用部分的之间?

1
2
3
4
let s = String::from("hello world");

let hello = &s[0..5];
let world = &s[6..11];