一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情。
所有权内存分配
字符串字面值 let s = "hello"
字面值不能被修改 String 类型可以被修改,需要在hap 上分配内存
rust 中变量走出作用域 调用drop方法
值的移动 move
let x = 5;
let y =x;
xy都是基础类型,xy都被压入栈中
let s1 = String::from("hello");
let s2 = s1;
此时 s1赋值给s2是s1被move ,s1 将不能被使用
这样避免了二次释放
rust 同样有深拷贝,只是针对 heap上的对象
let s1 = String::from("hello");
let s2 = s1.clone();
栈上数据都实现了 copy trait 所以x在之前的例子一直有效
标量类型都是实现了copy的,元组里面如果都是标量的话他也是可以copy的
函数的所有权
fn main() {
let s1 = gives_ownership(); // gives_ownership 将返回值
// 转移给 s1
let s2 = String::from("hello"); // s2 进入作用域
let s3 = takes_and_gives_back(s2); // s2 被移动到
// takes_and_gives_back 中,
// 它也将返回值移给 s3
} // 这里, s3 移出作用域并被丢弃。s2 也移出作用域,但已被移走,
// 所以什么也不会发生。s1 离开作用域并被丢弃
fn gives_ownership() -> String { // gives_ownership 会将
// 返回值移动给
// 调用它的函数
let some_string = String::from("yours"); // some_string 进入作用域.
some_string
// 返回 some_string
// 并移出给调用的函数
// }
// takes_and_gives_back 将传入字符串并返回该值
fn takes_and_gives_back(a_string: String) -> String {
// a_string 进入作用域
a_string
// 返回 a_string 并移出给调用的函数
}
- 变量传给方法就跟赋值给变量是一样的会发生移动或者复制
- 返回值同样会发生所有权转移
- 一个值赋值给其他变量的时候发生移动
- heap 离开作用域会被 drop 清理
引用和借用
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()
}
为了避免所有权转移,引用类似指针 跟创建默认变量一样,创建引用是不能修改操作的
fn main() {
let s = String::from("hello");
change(&s);
}
fn change(some_string: &String) { some_string.push_str(", world");
}
和let mut 相同增加 mut 可以改成可变引用
fn main() {
let mut s = String::from("hello");
change(&mut s); }
fn change(some_string: &mut String) {
some_string.push_str(", world");
}
但是不允许同时创建两个相同的引用的,避免数据竞争 不能同时拥有一个可变引用一个不可变引用 可以同时拥有两个不可变引用 引用的值必须还在作用域之内