rust 语法和语义 09 所有权

rust 语法和语义 09 所有权

所有权:ownership

rust 所追求最大的目标 – 内存安全,其关键在于所有权。

mint:而我理解的安全的基础核心之一为 { } 作用域

所有权概念将依照官方介绍,分为3个部分说明:

  • 所有权 ownership
  • 引用和借用 references and borrowing
  • 生命周期 lifetimes

概述

  • 绑定 有 所绑定的的值 的 所有权。
  • 对于任何给定的资源 有且仅有 一个绑定与之对应。

原则 meta

rust注重:安全速度 。通过 零开销抽象 zero-cost abstractions 来实现。即这些分析都在 编译时 完成,而不需要再运行时付出开销。

所有权系统是一个典型的零开销抽象的例子。

所有权 ownership

绑定 有 所绑定的的值 的 所有权。

这意味着:当一个绑定离开 作用域 ,它们绑定的资源就被释放。

移动语义 move semantics

简称为 移动 move。对应后文所说的 拷贝 copy

对于任何给定的资源 有且仅有 一个绑定与之对应。

把一个绑定赋予另一个绑定时,

let v = vec![1, 2, 3];
let v2 = v;
println!("v[0] is: {}", v[0]); // error: use of moved value

把变量作为参数传递给函数之后使用这个变量时,

fn take(v: Vec<i32>) {}
let v = vec![1, 2, 3];
take(v);
println!("v[0] is: {}", v[0]); // error: use of moved value

移动的本质

栈stack 上分配 (copy)
let x = 10;
  • 栈stack 上为 x 分配了一个 i32 大小的内存。
  • 将值 10 拷贝copy 到上述内存中。
  • 将此内存区域 绑定 到变量 x 上,以供进一步 引用
堆heap 上分配 (move)
let v = vec![1, 2, 3];

相比 栈stack堆heap 在两个内存区域分配了内存。

  • 栈stack 上为 v 分配了一个内存。
    • 拷贝copy 堆上分配的内存地址 到一个 数据指针 上。作为栈上 v 的一部分。
  • 堆heap 上为 [1, 2, 3] 分配了一个内存。

然后,

let mut v2 = v;
  • 只将 栈stack 上 v 的内容 浅拷贝copy 到 v2 上。
  • 不拷贝 堆heap 上的内容。

相当于 指针拷贝,现在有 v 和 v2 同时指向同一个 堆heap 地址了。

这引入了 数据竞争不安全 的!

因为一个指针改变了堆上的数据,比如,改变了堆的大小。另一个指针将一无所知!。

这就是为什么移动语义起作用的原因。

mint:所以,推测栈上处理数据指针外,还有的数据内容是所有权信息吧。


copy类型

  • 当一个绑定的所有权被 移动 move 到另一个绑定后,不能使用之前的绑定。
  • copy 是一种 trait,可以帮助使用之前的绑定。

trait

trait 简单理解为:一个标记,能为 特定类型 增加 额外行为

基本数据类型

正如 移动的本质 - 栈stack 上分配 (copy) 章节所描述。

  • 像一个 移动move,当我们把 v 赋值给 v2 时, 产生了一个数据的拷贝。
  • 但不同 移动move 的是,如作为基本数据类型的 i32 并没有指向其它数据的指针。
  • 这个一个 完全拷贝copy

所以,基本数据类型(请参看:trait描述部分-还未编写) 都实现了 Copy trait


参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值