essay | tech | year-summary | about
日期:2021-04-27T00:00:00Z
RUST因为只允许同时有一个变量指向一个heap内存中的空间
为了编程的简易性,所以有Reference这个概念
在s1进入函数后,s1并没有被解除与”hello”的关联
fn main() {
let s1 = String::from("hello");
let len = calculate_length(&s1);
println!("The length of '{}' is {}.", s1, len);
}
fn calculate_length(s: &String) -> usize {
s.len()
}
具体的变量指向,如图所示
Reference使用的变量空间,属于借用(Brrow),所以在被释放后不会影响内存空间
let s1 = String::from("hello");
let len = calculate_length(&s1);
fn calculate_length(s: &String) -> usize { // s is a reference to a String
s.len()
} // Here, s goes out of scope. But because it does not have ownership of what
// it refers to, nothing happens.
Reference使用的变量属于借用,不可编辑
fn main() {
let s = String::from("hello");
change(&s);
}
fn change(some_string: &String) {
// !error
// error[E0596]: cannot borrow `*some_string` as mutable, as it is behind a `&` reference
some_string.push_str(", world");
}
解决案
带入&mut
fn main() {
let mut s = String::from("hello");
change(&mut s);
}
fn change(some_string: &mut String) {
some_string.push_str(", world");
}
&mut的限制
在同一个scope内,只允许有且同时有一个&mut
下边的代码会报错
let mut s = String::from("hello");
let r1 = &mut s;
let r2 = &mut s;
// !error
// error[E0499]: cannot borrow `s` as mutable more than once at a time
println!("{}, {}", r1, r2);
下面的是ok的例子
let mut s = String::from("hello");
{
let r1 = &mut s;
} // r1 goes out of scope here, so we can make a new reference with no problems.
let r2 = &mut s;
因为r1,r2不再被使用
这个代码也没有问题
let mut s = String::from("hello");
let r1 = &s; // no problem
let r2 = &s; // no problem
println!("{} and {}", r1, r2);
// r1 and r2 are no longer used after this point
let r3 = &mut s; // no problem
println!("{}", r3);
但是下面的会报错,因为同时只能有一个&mut
let mut s = String::from("hello");
let r1 = &s; // no problem
let r2 = &s; // no problem
let r3 = &mut s; // BIG PROBLEM
// error
// error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable
println!("{}, {}, and {}", r1, r2, r3);
Dangling reference指的是pointer指向一块已经被释放的空间。操作这个pointer的行为是不可预测的
Rust从语言上无法生成一个dangling reference
fn main() {
let reference_to_nothing = dangle();
}
fn dangle() -> &String {
let s = String::from("hello");
// error
// error[E0106]: missing lifetime specifier
&s
}
为了防止dangling问题,
上面代码应该用下面方式来返回
fn no_dangle() -> String {
let s = String::from("hello");
s
}