关于所有权
通常在 C/Cpp 中, 假设我们用一个指针指向一块申请的内存区域
char *p = (char *) malloc(50);
复制代码
假设这个 p
携带了数据, 刚好有个函数需要使用到 p
携带的数据, 那么就像这样
#include <stdio.h>
#include <string.h>
void foo(char *p) {
*p = NULL;
}
int main(int argc, char **argv) {
char *p = (char *) malloc(50);
strcpy(p, "test");
printf("%s\n", p);
foo(p);
printf("%s\n", p);
return 0;
}
复制代码
foo
你不看函数实现根本不晓得内部会做什么事, 是否进行了 free
操作等等. 就像这里, 函数内部把指针设成 NULL
, 你外部也不晓得.
Rust 通过引入一个 ownership 的概念来解决此类问题.
Ownership
我们可以定义一个变量来理解.
let a = String::from("test");
复制代码
一般我们都会讲给变量 a
赋一个 String
类型的值, 但是 Rust 里的说法是, 给 a
绑定一个 String
类型的值, 为什么要这么讲嘞.
首先绑定就是当前情况下, String
类型的这个值, 只有 a
这一个管理者, 所以 a
就是值的所有者, a
离开当前的作用域, a
就被处理掉, 包括它所管理的值. 这就是 ownership 的概念.
Move
然后就是 move
, 这个概念很好理解, 就是变量的 ownership
转移的行为. 我们的变量 a
现在拥有了它的值的所有权, 要是绑定的时候再加个 mut
, 还能改变值. 我要是再把它绑定给其他的变量, 自然也是可以的, 但是同时得把关于这个值的 ownership
交出来.
let mut a = String::from("test");
a = String::from("foo");
a.push_str("bar");
println!("{}", a);
let b = a;
复制代码
现在, 我们的 a
已经没法用了, 也就是 a
的 ownership
已经 move
给 b
了. 有一点要搞清爽的就是, 起初 a
是 String
类型值的所有者, 但是当权力变更的时候, a
就没了, 而 String
类型的值直接转交给了 b
.
Move 在很多地方发生
fn main() {
let a = foo();
bar(a);
}
fn bar(s: String) {
println!("{}", s);
}
fn foo() -> String {
let a = String::from("bar");
a
}
复制代码
这些函数传参, 返回值都会发生 move
.
好吧, 这次我不会管挖不管埋了, 好好写完这一系列.