课程名称:领略Rust之美,挑战双高语言
课程章节: 第3章 Rust进阶
主讲老师:叶枭
课程内容:
今天学习的内容是 Rust 中所有权的另一个知识点,借用和引用。
引入一个场景,有一个 reverse
函数,用于将一个字符串值进行反转:
fn reverse(s: String) -> String {
s.chars().rev().collect()
}
fn main() {
let s1 = String::from("hello");
let s2 = reverse(s1);
println!("{} {}", s1, s2);
}
按照前面所学的所有权的知识,在调用 reverse
时,变量 s1 对字符串值的所有权就交给了函数,所以当前作用域下 s1 不再有效,打印 s1 就会报错。
那么如果 s1 还有用处,就是需要打印 s1 呢?
Rust 提供了引用的功能,来实现这个需求。
引用
声明变量时,和之前没有区别:
let s1 = String::from("hello");
再函数调用传参时,需要在变量前面加上 &
表示这是一个引用值,它能允许在不转移所有权的情况下使用值。
let s2 = reverse(&s1);
这里的 &s1
允许在不转移所有权的前提下,创建一个指向 s1
值的引用。引用不拥有值的所有权,所以将 &s1
引用作为参数传给函数后,在当前作用域下,变量 s1
依然拥有字符串值的所有权,这样 s1
就能正常打印而不会报错了。
借用
那么函数内部如何使用引用呢?
函数在声明时,在参数类型前加上 &
来表示该参数的类型是一个引用。
fn reverse1(s: &String) -> String {
s.chars().rev().collect()
}
这种通过引用传递参数给函数的方法也被称为借用(borrowing)。
引用的规则
从上面使用运用的示例中,我们能总结出一些规则:
1.使用引用类型不会获得所有权
2.默认情况下引用是不可变的
3.同一时间最多只能存在一个可变引用(防止多线程下的数据竞争)
课程收获
这节课学习了 Rust 中所有权中有一个很重要的概念,引用和借用。通过引用,可以避免所有权的转移,方便在作用域下对变量的使用,在开发中用的非常多。