rust学习(第六天)

20.Rust所有权
它是 Rust 语言为高效使用内存而设计的语法机制。所有权概念是为了让 Rust 在编译阶
段更有效地分析内存资源的有用性以实现内存管理而诞生的概念。

所有权规则:
rust中的每个值都有一个变量,称为其所有者。
一次只能有一个所有者
当所有者不在程序运行范围时,该值将被删除

变量范围
{
// 在声明以前,变量 s 无效
let s = “runoob”;
// 这里是变量 s 的可用范围
}
// 变量范围已经结束,变量 s 无效
变量范围是变量的一个属性,其代表变量的可行域,
默认从声明变量开始有效直到变量所在域结束。

内存和分配
一种在程序运行时程序自己申请使用内存的机制——堆。
决定资源是否浪费的关键因素就是资源有没有及时的释放。
rust变量范围结束的时候,Rust 编译器自动添加了调用释放资源函数的步骤。

变量与数据交互的方式
变量与数据交互方式主要有移动(Move)和克隆(Clone)两种:

移动
多个变量可以在 Rust 中以不同的方式与相同的数据交互:
let x = 5;
let y = x;
现在栈中将有两个值,在此情况中的数据是"基本数据"类型的数据,
不需要存储到堆中,仅在栈中的数据的“移动”方式是直接复制,
这不会花费更长的时间或更多的存储空间。"基本数据"类型有这些:
所有整数类型,例如 i32 、 u32 、 i64 等。
布尔类型 bool,值为 true 或 false 。
所有浮点类型,f32 和 f64。
字符类型 char。
仅包含以上类型数据的元组(Tuples)。

但是如果交互的数据发生在堆中就是另一种情况:
let s1 = String::from(“hello”);
let s2 = s1;
第一步产生一个String对象,值为“hello”。其中“hello”可以是类似于长度
不确定的数据,需要在堆中存储。
为了确保安全,在给 s2 赋值时 s1 已经无效了。
没错,在把 s1 的值赋给 s2 以后 s1 将不可以再被使用。
下面这段程序是错的:

let s1 = String::from(“hello”);
let s2 = s1;
println!("{}, world!", s1); // 错误!s1 已经失效

但是使用普通的赋值语句是不会发生这种情况的

克隆
单纯的复制
fn main() {
let s1 = String::from(“hello”);
let s2 = s1.clone();
println!(“s1 = {}, s2 = {}”, s1, s2);
}
这里是真的将堆中的"hello"复制了一份,所以s1和s2都分别绑定了一个值。

涉及函数的所有权机制
????
将一个变量当作函数的参数传给其他函数,那么他和移动的效果是一样的

引用与租借
引用可以看做一种指针
实质上“引用”是变量的间接访问方式。
fn main() {
let s1 = String::from(“hello”);
let s2 = &s1;
println!(“s1 is {}, s2 is {}”, s1, s2);
}
&运算符可以取变量的“引用”。
当一个变量的值被引用时,变量本身不会被认定无效。
“引用”并没有在栈中复制变量的值;
函数参数传递的道理一样。

引用不会获得值的所有权。
引用只能租借(Borrow)值的所有权。
引用本身也是一个类型并具有一个值,这个值记录的是别的值所在的位置,
但引用不具有所指值的所有权。
fn main() {
let s1 = String::from(“hello”);
let s2 = &s1;
let s3 = s1;
println!("{}", s2);
}
这段程序不正确:因为 s2 租借的 s1 已经将所有权移动到 s3,
所以 s2 将无法继续租借使用 s1 的所有权。如果需要使用 s2 使用该值,
必须重新租借。

我的理解:引用只是把我的所有权借给你,但是所有权还是属于我自己的
,就算你借了我的所有权,一旦我把所有权转移(=赋值)给其它的变量,
那么原本借用了我的所有权的变量的值也将不负存在。

同样的,租借的所有权不能修改所有者的值。

可变的租借方式
fn main() {
let mut s1 = String::from(“run”);
// s1 是可变的

let s2 = &mut s1;
// s2 是可变的引用

s2.push_str("oob");
println!("{}", s2);

}
我们用&mut修饰可变的引用类型。
可变引用与不可变引用相比除了权限不同以外,可变引用不允许多重引用
但不可变引用可以:
Rust 对可变引用的这种设计主要出于对并发状态下发生数据访问碰撞的考虑,
在编译阶段就避免了这种事情的发生。
由于发生数据访问碰撞的必要条件之一是数据被至少一个使用者写且同时被
至少一个其他使用者读或写,所以在一个值被可变引用时不允许再次被任何
引用。

垂悬引用
指那种没有实际指向一个真正能访问的数据的指针(不一定是空指针,还有可能是已经释放的资源
)。他们就像失去悬挂物体的绳子,所以叫“垂悬引用”。
“垂悬引用”在Rust语言里不允许出现,如果有,编译器会发现它。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值