首页 > 其他分享 >《Rust权威指南》学习笔记——4. 认识所有权

《Rust权威指南》学习笔记——4. 认识所有权

时间:2023-02-09 00:22:21浏览次数:48  
标签:指南 mut String 作用域 s1 笔记 let Rust

Rust权威指南学习笔记——认识所有权

什么是所有权

1. 所有权规则

  • Rust中的每一个值都有一个对应的变量作为它的所有者。
  • 在同一时间内,值有且仅有一个所有者。
  • 当所有者离开自己的作用域时,它持有的值就会被释放掉。

2. 变量作用域

  • s在进入作用域后变得有效。
  • 它会保持自己的有效性直到自己离开作用域为止。

Rust在变量离开作用域时,会调用一个叫作drop的特殊函数。

3.移动

为了确保内存安全,同时也避免复制分配的内存,Rust在这种场景下会简单地将s1废弃,不再视其为一个有效的变量。因此,Rust也不需要在s1离开作用域后清理任何东西。

let s1 = String::from("hello");
let s2 = s1;

println!("{}, world!", s1);

4. 克隆:深拷贝

let s1 = String::from("hello");
let s2 = s1.clone();

println!("s1 = {}, s2 = {}", s1, s2);

5. Copy的trait

let x = 5;
let y = x;

println!("x = {}, y = {}", x, y);
// x = 5, y = 5

以上代码没有调用clone,x在被赋值给y后也依然有效,且没有发生移动现象。这是为什么?

  • 一旦某种类型拥有了Copy这种trait,那么它的变量就可以在赋值给其他变量之后保持可用性。
  • 如果一种类型本身或这种类型的任意成员实现了Drop这种trait,那么Rust就不允许其实现Copy这种trait。
  • 一些拥有Copy trait的类型
    • 所有的整数类型,诸如u32。
    • 仅拥有两种值(true和false)的布尔类型:bool。
    • 字符类型:char。
    • 所有的浮点类型,诸如f64。
    • 如果元组包含的所有字段的类型都是Copy的,那么这个元组也是Copy的。例如,(i32, i32)是Copy的,但(i32, String)则不是。

引用与借用

(1)引用

let s1 = String::from("hello");

let len = calculate_length(&s1);

...

fn calculate_length(s: &String) -> usize { // s 是一个指向 String 的引用
    s.len()
} // 到这里,s离开作用域。但是由于它并不持有自己所指向值的所有权,
//所以没有什么特殊的事情会发生
  • 这些&代表的就是引用语义,它们允许你在不获取所有权的前提下使用值。
  • 与变量类似,引用是默认不可变的,Rust不允许我们去修改引用指向的值。以下编译出错。
fn main() { 
    let s = String::from("hello"); 
 
    change(&s); 
} 
 
fn change(some_string: &String) { 
    some_string.push_str(", world"); 
} 

(2)可变引用

  • 首先,我们需要将变量s声明为mut,即可变的。其次,我们使用&mut s来给函数传入一个可变引用,并将函数签名修改为some_string: &mut String来使其可以接收一个可变引用作为参数。
fn main() { 
    let mut s = String::from("hello"); 
 
    change(&mut s); 
} 
 
fn change(some_string: &mut String) { 
    some_string.push_str(", world"); 
}
  • 对于特定作用域中的特定数据来说,一次只能声明一个可变引用。

cannot borrow 's' as mutable more than once at a time...

let mut s = String::from("hello"); 
 
let r1 = &mut s; 
let r2 = &mut s; 

好处:避免数据竞争。

数据竞争(data race)与竞态条件十分类似,它会在指令满足以下3种情形时发生:
• 两个或两个以上的指针同时访问同一空间。
• 其中至少有一个指针会向空间中写入数据。
• 没有同步数据访问的机制。

(3)悬垂引用

使用拥有指针概念的语言会非常容易错误地创建出悬垂指针。这类指针指向曾经存在的某处内存地址,但该内存已经被释放掉甚至是被重新分配另作他用了。而在Rust语言中,编译器会确保引用永远不会进入这种悬垂状态。假如我们当前持有某个数据的引用,那么编译器可以保证这个数据不会在引用被销毁前离开自己的作用域。

标签:指南,mut,String,作用域,s1,笔记,let,Rust
From: https://www.cnblogs.com/qiangz/p/17103821.html

相关文章

  • 2-SAT-学习笔记
    基本知识复习https://oi-wiki.org/graph/2-sat/模板【模板】2-SAT问题#include<bits/stdc++.h>#definelllonglongusingnamespacestd;constintN=2e6+5;......
  • PyQt5-快速上手笔记
    窗口importsysfromPyQt5.QtWidgetsimportQApplication,QWidgetfromPyQt5.QtGuiimportQIconclassExample(QWidget):def__init__(self):super(......
  • Redis课程笔记
    Redis安装前台启动后台启动1)备份redis.conf2)修改配置:deamonizeyes3)执行redis-server配置文件的目录key键操作select[dbindex]切换库keys*查所有key......
  • 树链剖分 学习笔记
    树链剖分学习笔记树链剖分(Treedecomposition),顾名思义,是一种将树剖分为若干条链,使得可以用数据结构维护树上信息的数据结构。树链剖分有多种意思,包括重链剖分、长链剖分......
  • FL论文笔记 Hierarchically Fair Federated Learning,Shapley计算贡献
    相关笔记:https://blog.csdn.net/wuxusanren/article/details/128651334相关综述论文:《ASurveyofIncentiveMechanismDesignforFederatedLearning》《联邦学习激励......
  • 一点seq2seq的笔记
    一点seq2seq的笔记Date:2023-02-08T21:33:00+08:00毕设,看了点神经网络的内容。RNN的输入是asequenceofvector,感觉RNN像在训练一个cell,喂给cell一个vector......
  • rust 配置国内源,加速
    [source.crates-io]registry="https://github.com/rust-lang/crates.io-index"#指定镜像replace-with='tuna'#清华大学[source.tuna]registry="https://mi......
  • 《代码整洁之道》 读书笔记 一、整洁代码
    1.整洁代码1.1要有代码代码不再是问题;我们应当关注模型和需求。代码很快就能自动产出。这种言论是不正确的。因为代码呈现了需求的细节,在某些层面上,这些细节无法被忽......
  • 自我介绍&学习笔记
    这个作业属于哪个课程https://edu.cnblogs.com/campus/fzzcxy/2023learning这个作业要求在哪里https://edu.cnblogs.com/campus/fzzcxy/2023learning/homework/1......
  • 第三天笔记
    第三天笔记程序控制语句条件控制语句(根据不同的条件进入不同的代码块)循环控制语句(根据循环条件进行多次循环)循环控制语句流程定义初始值设置迭代条件......