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) 想想一下:如果传递的是一份复 ...
随机推荐
- 图与网络分析—R实现(一)
图与网络 一个网络G,也可以称为图(graph)或网络图,是一种包含了节点V(即网络参与者,也称顶点)与边E(即节点之间的连接关系)的数学结构,记作G={V,E}.可以使用一个矩阵来存放节点之间的连接 ...
- python入门教程之二十三Python3 MySQL 数据库连接 - PyMySQL 驱动
MySQL 是最流行的关系型数据库管理系统,如果你不熟悉 MySQL,可以阅读我们的 MySQL 教程. 本章节我们为大家介绍使用 mysql-connector 来连接使用 MySQL, mysql ...
- [Linux]CentOS7:卸载、安装Java JDK
JDK(Java Development Kit)是Java语言的软件开发工具包,包括Java运行环境.Java开发工具.Java基础类库. JRE(Java Runtime Environment) ...
- sync.Pool:提高Go语言程序性能的关键一步
1. 简介 本文将介绍 Go 语言中的 sync.Pool并发原语,包括sync.Pool的基本使用方法.使用注意事项等的内容.能够更好得使用sync.Pool来减少对象的重复创建,最大限度实现对象的 ...
- python去掉重复值的方法--四种
my_list = [1,1,1,1,2,3,3,3,4,5,5,56,6,7,77,7,5,5,3]# 集合法:缺点是结果会打乱原始数据的顺序print(set(my_list)) # 列表法:缺点 ...
- Gpssworld仿真(二):并排排队系统模拟
4.3 某一个加油站能够配给三个级别的燃油:①家庭取暖用的燃油:②轻工业用的燃油:③运输用的燃油.每一级别的燃油都有一个对应的油泵.订单中燃油的数量在3000加仑和5000加仑中变化,每次增加10加仑 ...
- c语言趣味编程(1)百钱百鸡
一.问题描述 百钱买百鸡问题:公鸡五文钱一只,母鸡三文钱一只,小鸡三只一文钱,用100文钱买100只鸡,公鸡.母鸡.小鸡各买多少只 二.设计思路 (1)定义三个变量下x,y,z代表公鸡,母鸡,小鸡的数 ...
- JAVA注解@Scheduled 不执行
spring boot项目需要在启动类加上注解 @EnableScheduling 定义一个接口 StockTask.java 1 public interface StockTask { 2 pub ...
- Java线程中断机制
在阅读AQS源码以及juc包很多基于AQS的应用源码过程中,会遇到很多interrupted相关的方法,这里复习一下java线程中断相关. 要点:使用interrupt()中断一个线程,该方法只是标记 ...
- 2022-08-30:给你一个字符串化学式 formula ,返回 每种原子的数量 。 原子总是以一个大写字母开始,接着跟随 0 个或任意个小写字母,表示原子的名字。 如果数量大于 1,原子后会跟着数
2022-08-30:给你一个字符串化学式 formula ,返回 每种原子的数量 . 原子总是以一个大写字母开始,接着跟随 0 个或任意个小写字母,表示原子的名字. 如果数量大于 1,原子后会跟着数 ...