Rust函数参数传递的一个观点
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函数参数传递的一个观点的更多相关文章
- shell 脚本之获取命令输出字符串以及函数参数传递
在ubuntu 14.04之后,所有的U盘挂载也分用户之分,最近很多操作也和U盘有关,所以就研究了一上午shell脚本函数以及字符串操作的方法. 字符串操作: 获取他的命令输出比较简单,打个简单的比方 ...
- Python语言特性之1:函数参数传递
问题:在Python文档中好像没有明确指出一个函数参数传递的是值传递还是引用传递.如下面的代码中"原始值"是不放生变化的: class PassByReference: def _ ...
- C#函数参数传递解惑
C#语言函数参数的传递 就像C语言众多的后世子孙一样,C#的函数参数是非常讲究的.首先,参数必须写在函数名后面的括号里,这里我们有必要称其为形参.参数必须有一个参数名称和明确的类型声明.该参数名称 ...
- C#之委托(函数参数传递)【转】
原文:http://blog.csdn.net/wangdan199112/article/details/18796527 在学委托这块儿的时候,函数参数这块不是很理解,于是针对一个例子做了深入的理 ...
- Python 函数参数传递机制.
learning python,5e中讲到.Python的函数参数传递机制是对象引用. Arguments are passed by assignment (object reference). I ...
- java面试题:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
答:是值传递.Java编程语言只有值传递参数. 当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本.指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用 ...
- C语言学习笔记 (005) - 二维数组作为函数参数传递剖析
前言 很多文章不外乎告诉你下面这几种标准的形式,你如果按照它们来用,准没错: //对于一个2行13列int元素的二维数组 //函数f的形参形式 f(int daytab[2][13]) {...} / ...
- c++指向指针的指针与 c++指针作为函数参数传递问题
一直搞不明白,c++中指针到底是个啥东西,今天遇到到c++,指向指针的指针的问题,突然有点开窍了. 举个例子: int main(int argc, char** argv){ int a[5]={1 ...
- (C++)函数参数传递中的一级指针和二级指针
主要内容: 1.一级指针和二级指针 2.函数指针传递的例子 3.什么时候需要传递二级指针? 4.二级指针在链表中的使用 1.一级指针和二级指针 一级指针:即我们一般说的指针,就是内存地址: 二级指针: ...
- **Python的函数参数传递 和 global
函数的参数到底是传递的一份复制的值,还是对内存的引用? 我们看下面一段代码: a = [] def fun(x): x.append(1) fun(a) print(a) 想想一下:如果传递的是一份复 ...
随机推荐
- 解决class path resource [applicationContext.xml] cannot be opened because it does not exist
在学习spring的过程出现class path resource [applicationContext.xml] cannot be opened because it does not exis ...
- QML 界面切换的几种方法(带示例代码)
QML 界面切换的几种方法(带示例代码)
- pychearm日常用法
一 常用快捷键 编辑类:Ctrl + D 复制选定的区域或行Ctrl + Y 删除选定的行Ctrl + Alt + L 代码格式化Ctrl + Al ...
- [Python]Python安装教程
anaconda Anaconda:python的一种软件发行版.Anaconda发行版会预装很多pydata生态圈里的软件,而Miniconda是最小的conda安装环境, 一个干净的conda环境 ...
- [PKM] 个人知识管理
1 个人知识管理的需求 1.1 背景 随着信息大爆炸,碎片化的知识越来越多,原来中小学阶段在学校中习得的.传统的.基于纸质笔记的知识管理方式已不能满足当前的诉求. 传统的基于纸质笔记的知识管理方式 工 ...
- 四月二十六java基础知识
1..对文件的随机访问:前面介绍的流类实现的是磁盘文件的顺序读写,而且读和写分别创建不同的对象,java语言中还定义了一个功能强大.使用更方便的随机访问类RandomAcessFile它可以实现文件的 ...
- Java设计模式 —— 工厂模式
3 简单工厂模式 3.1 创建型模式 Creational Pattern 关注对象的创建过程,对类的实例化过程进行了抽象,将软件模块中对象的创建和对象的使用分离,对用户隐藏了类的实例的创建细节.创建 ...
- handler+looper+messagequeue源码解析
https://www.jianshu.com/p/b4d745c7ff7ahandler机制源码1.handler机制的作用在多线程的场景中,将子线程中需要更新UI的操作信息传递到UI主线程.多个线 ...
- RDIFramework.NET代码生成器全新V5.1版本发布
RDIFramework.NET代码生成器介绍 RDIFramework.NET代码生成器,代码.文档一键生成. RDIFramework.NET代码生成器集代码生成.各数据库对象文档生成.数据库常用 ...
- Linux云计算运维工程师day28shell编程基础
一. 1.全局变量.环境变量 Export OLDOBY="I am a oldboy." Echo OLDOBY OLDOBY="I am a oldboy.&quo ...