所有权
介绍
rust 在变量离开作用域时会调用drop()
释放内存.
| {
let s = String::from("hello"); // 从此处起,s 是有效的
// 使用 s
} // 此作用域已结束,
// drop(s), s 不再有效
|
注意, 所有权概念只是堆上内存概念, 栈内存不用:
| let j;
{
let i="STR";
j=i;
}
print!("{}", j);
|
移动
考虑如下代码:
| {
let s1 = String::from("h/ello");
let s2 = s1;
println!("{}, world!", s1);
}
|
如果 drop(s1) 和 drop(s2), 那么double free, rust 在s2=s1
时将s1所有权交给s2, 因此println处会报错.
同样的, 调用函数也会转移所有权:
| fn main(){
let a=String::from("aaa");
func(a);
println!("{}", a); // 报错
}
fn func(a:String){
// do sth.
}
|
解法是使用引用, 借用变量所有权:
| fn calculate_length(s: &String) -> usize {
s.len()
}
fn change(s: &mute String) {
s.push_str("a");
}
|
可变引用在同一时间只能创建一个, 可变引用在同一时间内不可以与非可变引用同时创建:
| let mut s = String::from("hello");
let r1 = &mut s;
let r2 = &mut s; // 报错
|
| let mut s = String::from("hello");
let r1 = s;
let r2 = &mut s; // 报错
|
解决方法是创建代码块:
| let mut s = String::from("hello");
{
let r1 = &mut s;
} // r1 在这里离开了作用域,所以我们完全可以创建一个新的引用
let r2 = &mut s;
|
Slices
| fn slice_word(s: &str) -> &str{
&s[..2];
&s[2..];
return &s[0..2];
}
fn main() {
let a=String::from("hello");
let b=slice_word(&a);
println!("{}",b);
}
|