Rust-所有权系统

2017-12-21  本文已影响0人  42bf8ea9aeb1

今天学习Rust中的所有权系统。按照官方教程所述,所有权系统包含三个部分:

看完发现,C++吭哧吭哧从99发展到11、14、17标准,Rust早就在山顶等它了。下面还是流水账记录心得体会。

Rust利用移动语义 (Move semantics) 确保: 任何给定的资源正好只有一个绑定与之对应。教程中有个例子解释了这一点:

let v = vec![1,2,3];
let v2 = v;
println!("v[0] is : {}", v[0]);

这个例子是无法编译通过的。其原因是当用v2绑定v的时候,v这个绑定就自动失效了,v原本的资源转移到了v2。这个效果和c++11早期的智能指针auto_ptr很像。当auto_ptr拷贝赋值给另一个auto_ptr时,原指针会被置为null。
当时因为auto_ptr这个特性踩过坑,后来auto_ptr被unique_ptr替代,换成了更温和的std::move语句,要求用户显式调用move语句来完成资源所有权的转移。现在看来,C++当时可能的确是想对指针有更严格的控制,可惜抵挡不住舆论的压力,还是怂了。扯远了,继续回来学习。

默认的移动语义带来的问题是,当我想在绑定后仍然访问原变量值,就必须手动重新绑定。不想那么麻烦那就要用到 所有权系统 的第二个特性,借用。借用是通过两种引用方式以及一系列必须遵守的规则来实现的。

let y: &i32;
{
    let x = 5;
    y = &x;
}

println!("{}", y);

当离开大括号区域后,x绑定的资源会被释放,如果y还绑定着x,且后续还有对y的访问操作,那势必会造成崩溃。幸运得是,Rust不会让这段程序通过编译。因为y在x之前申明,也就是意味着,y比x的生命周期更长,这不符合绑定的规则。

在C++中也有生命周期的概念,比如static是全局生命周期,栈上分配的变量只存在于外层大括号所在区域。堆上分配的变量取决于用户何时申请和释放。在Rust中可以给变量显式地指明生命周期。

上一篇 下一篇

猜你喜欢

热点阅读