Q5: 一个函数的观点
A5: Rust中的每个函数都是自治的,在每一个函数体中,相当于重新开辟了一个新的领域。
将参数传递给函数参数,与let声明一个绑定是一样的规则。

 1 ```
2 // 所有权语义
3 fn modify(mut v: Vec<u32>) -> Vec<u32> {
4 v.push(42);
5 v
6 }
7 let v = vec![1,2 ,3];
8 let v = modify(v); // 这里参数传递到modify执行的绑操作是, let mut v = v;是以所有权的方式转移的
9 println!("{:?}", v); // 1, 2, 3, 42
10
11 // 同上面进行对比
12 let v = vec![1, 2, 3];
13 let mut v = v; // 这里可以看出很多的问题了吧,使用到了变量遮蔽,将变量重新绑定的位可变的变量,这里是符合所有权的,因为还是只有一个值指向管理的内存,原来的v的所有权给了新的v,只不过这里的两个v是相同的名字而已。
14 v.push(42);
15 println!("{:?}", v);
16
17
18 // 借用
19 pub fn modify_ref_mut(v: &mut [u32]) {
20 v.reverse();
21 }
22 let mut v = vec![1,2,3];
23 modify(&mut v); // 这里参数传递到modify执行的绑定是,let v = &mut v; 是以可变引用的方式借用的
24 println!("{:?}", v); // 3, 2, 1
25
26 // 同上面对比
27 let mut v = vec![1, 2, 3];
28 let v = &mut v; // 声明了一个可变借用
29 v.reverse(); // 对可变借用进行操作
30 println!("{:?}", v);
31
32 // 可变借用和不可变借用同时存在
33 // Case 1 ok
34 let mut v = vec![1, 2, 3];
35
36 let v1 = &mut v; // 可变借用
37 v1.reverse();
38 println!("{:?}", v1); // 不可变借用
39
40 // 此时的 v 已经被v1改变了
41
42 let v2 = &v; // 不可变借用, 此时v2做出了一个不可变绑定
43 println!("{:?}", v2); // 不可变借用, 从上一句到这一句之间不会不发生v的任何变化ok
44
45 // Case 2 ok
46 let mut v = vec![1, 2, 3];
47
48 let v2 = &v; // 不可变借用
49 println!("{:?}", v2); // 不可变借用, 从上一句到这一句之间不会发生v的任何变化ok
50
51 // v1 可变借用了v
52
53 let v1 = &mut v; // 可变借用
54 v1.reverse();
55 println!("{:?}", v1);// 不可变借用
56
57 // Case 3 error
58 let mut v = vec![1, 2, 3];
59
60 let v2 = &v; // 不可变借用
61
62
63 // v1 可变借用了v
64 let v1 = &mut v; // 可变借用
65 v1.reverse();
66 println!("{:?}", v1);
67 println!("{:?}", v2); // 不可变借用, 这里的v2和上面声明的v2之间指向的v发生了变化,
68 及时没有任何的变化,在let v2 = &v; 和println!("{:?}", v2);有任何的可变借用都不可以。所以发生了借用规则的冲突问题。
 1  error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
2 --> src/lib.rs:75:14
3 |
4 73 | let v2 = &v;
5 | -- immutable borrow occurs here
6 74 |
7 75 | let v1 = &mut v;
8 | ^^^^^^ mutable borrow occurs here
9 ...
10 78 | println!("{:?}", v2);
11 | -- immutable borrow later used here

从这个例子可以看到的是, modify中参数的是被mut修饰是一个可变的,而传入的v是没有被mut
修饰的,这里参数传递进来进行了一次绑定操作,let mut v = v;
在函数modify的内部v与函数外部的v没有任何的关系,v被转移到了modify的内部。从这里可以
看出每一个函数是一个自治的。

Rust函数参数传递的一个观点的更多相关文章

  1. shell 脚本之获取命令输出字符串以及函数参数传递

    在ubuntu 14.04之后,所有的U盘挂载也分用户之分,最近很多操作也和U盘有关,所以就研究了一上午shell脚本函数以及字符串操作的方法. 字符串操作: 获取他的命令输出比较简单,打个简单的比方 ...

  2. Python语言特性之1:函数参数传递

    问题:在Python文档中好像没有明确指出一个函数参数传递的是值传递还是引用传递.如下面的代码中"原始值"是不放生变化的: class PassByReference: def _ ...

  3. C#函数参数传递解惑

    C#语言函数参数的传递   就像C语言众多的后世子孙一样,C#的函数参数是非常讲究的.首先,参数必须写在函数名后面的括号里,这里我们有必要称其为形参.参数必须有一个参数名称和明确的类型声明.该参数名称 ...

  4. C#之委托(函数参数传递)【转】

    原文:http://blog.csdn.net/wangdan199112/article/details/18796527 在学委托这块儿的时候,函数参数这块不是很理解,于是针对一个例子做了深入的理 ...

  5. Python 函数参数传递机制.

    learning python,5e中讲到.Python的函数参数传递机制是对象引用. Arguments are passed by assignment (object reference). I ...

  6. java面试题:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

    答:是值传递.Java编程语言只有值传递参数. 当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本.指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用 ...

  7. C语言学习笔记 (005) - 二维数组作为函数参数传递剖析

    前言 很多文章不外乎告诉你下面这几种标准的形式,你如果按照它们来用,准没错: //对于一个2行13列int元素的二维数组 //函数f的形参形式 f(int daytab[2][13]) {...} / ...

  8. c++指向指针的指针与 c++指针作为函数参数传递问题

    一直搞不明白,c++中指针到底是个啥东西,今天遇到到c++,指向指针的指针的问题,突然有点开窍了. 举个例子: int main(int argc, char** argv){ int a[5]={1 ...

  9. (C++)函数参数传递中的一级指针和二级指针

    主要内容: 1.一级指针和二级指针 2.函数指针传递的例子 3.什么时候需要传递二级指针? 4.二级指针在链表中的使用 1.一级指针和二级指针 一级指针:即我们一般说的指针,就是内存地址: 二级指针: ...

  10. **Python的函数参数传递 和 global

    函数的参数到底是传递的一份复制的值,还是对内存的引用? 我们看下面一段代码: a = [] def fun(x): x.append(1) fun(a) print(a) 想想一下:如果传递的是一份复 ...

随机推荐

  1. 全网最详细中英文ChatGPT-GPT-4示例文档-智能编写Python注释文档字符串从0到1快速入门——官网推荐的48种最佳应用场景(附python/node.js/curl命令源代码,小白也能学)

    目录 Introduce 简介 setting 设置 Prompt 提示 Sample response 回复样本 API request 接口请求 python接口请求示例 node.js接口请求示 ...

  2. 在 Kubernetes 集群上部署 VSCode

    在 Kubernetes 集群上部署 VSCode Visual Studio Code Visual Studio Code 是一个轻量级但功能强大的源代码编辑器,可在您的桌面上运行,适用于 Win ...

  3. 安装部署keepalived的HA环境

    每一台配置下keepalived #master01 配置: cat >/etc/keepalived/keepalived.conf<<"EOF" ! Conf ...

  4. 学习docker看此文足以

    什么是 Docker Docker 最初是 dotCloud 公司创始人  在法国期间发起的一个公司内部项目,它是基于 dotCloud 公司多年云服务技术的一次革新,并于 ,主要项目代码在  上进行 ...

  5. day16:Linux常用命令

    Linux中目录含义 /bin 存放普通用户的命令文件/boot 存放系统启动文件/cdrom 存放读取光盘的相关文件/dev 设备文件 /etc 配置文件/home 家目录/lib 库文件/lib6 ...

  6. python:selenium爬取boss网站被关小黑屋

    问题描述:使用selenium访问次数过多,被boss反爬封掉IP,这种方式有什么好一点的解决方法,首次可以用图形验证解封,今天访问次数过多,被关进了小黑屋 首次让我用图形界面解封 不过还好,手动解封 ...

  7. YII文件上传

    <span style="font-size:14px;">use yii\web\UploadedFile; public function actionDoarta ...

  8. 帝国cms7.5和7.2 搜素模板支持 php和灵动标签以及不起作用

    帝国CMS搜索模板不支持动态标签调用,从7.0到7.2再到刚发布的7.5,帝国官方团队始终没解决这个问题,这很不方便,但是帝国的强大可以让我们忽略这个问题,今天老威就把这个bug的解决方法说一下. 第 ...

  9. vue3+vant创建移动端项目,实战项目常见采坑记录

    前言: 产品背景介绍 我所做的这个项目,刚开始是没有移动端需求的,等PC端做完了上线使用了几个月后,突然有一天产品经理找到我说是要做一个在PC端添加一个快速注册入口,用手机微信扫二位码进入移动端注册页 ...

  10. 在void 中使用return的意思

    在定义的void函数里如果想要提前终止函数 格式为 return; 如果 在有返回值的函数中 格式为: return+值(0 -1 ......) 但如果在void 函数中写return 0 ; 则会 ...