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) 想想一下:如果传递的是一份复 ...
随机推荐
- idea创建Spring项目时选择Maven还是Spring initializr?
今天在使用idea创建Spring项目时不知道选择Maven还是Spring initializr 接着都实验了一下,其实本质是一样的,使用"spring initializr"创 ...
- 从pcap文件中提取pcma音频
操作系统 :Windows10_x64 .CentOS 7.6.1810_x64 wireshark版本:3.6.12 Python 版本 : 3.9.12 一.背景描述 工作中有时候会遇到需要从 ...
- Perceptron, Support Vector Machine and Dual Optimization Problem (1)
Linear Decision Boundary(线性决策边界) Example. (classification problem) 给定一个二元的特征空间 \(\mathcal{X} = \left ...
- pysimplegui之popup弹出框
弹出框其实跟信息框差不多,在写界面的时候经常用,具体如下 "高级呼叫"是以"弹出"开头的呼叫.它们是与用户沟通的最基本形式.它们以它们创建的窗口类型命名,即弹出 ...
- [MAUI 项目实战] 手势控制音乐播放器(四):圆形进度条
@ 目录 关于图形绘制 创建自定义控件 使用控件 创建专辑封面 项目地址 我们将绘制一个圆形的音乐播放控件,它包含一个圆形的进度条.专辑页面和播放按钮. 关于图形绘制 使用MAUI的绘制功能,需要Mi ...
- 扯下@EventListener这个注解的神秘面纱。
你好呀,我是歪歪. 前段时间看到同事在项目里面使用了一个叫做 @EventListener 的注解. 在这之前,我知道这个注解的用法和想要达到的目的,但是也仅限于此,其内部工作原理对我来说是一个黑盒, ...
- 快速重拾 Tmux
Tmux 是一个 Linux (Mac OS也支持)下的终端复用器,相较于 Screen 更为强大,但快捷键和操作逻辑也更复杂,一段时间不用,就很容易忘记相关的命令和快捷键.本文旨在通过一个简单的场景 ...
- 【Spring5】IOC
1 Spring概念 Spring是轻量级的开源JavaEE框架.可以解决企业开发的复杂性. Spring有两个核心部分:IOC和Aop ①IOC控制反转:把创建对象过程交给Spring管理 ②Aop ...
- Java Stream常见用法汇总,开发效率大幅提升
本文已经收录到Github仓库,该仓库包含计算机基础.Java基础.多线程.JVM.数据库.Redis.Spring.Mybatis.SpringMVC.SpringBoot.分布式.微服务.设计模式 ...
- if elseif else 怎么用?
问题:求三个数中的最大值 上代码-- 第一种 两两比较 每次取较大值 和第三个值比较 最终得到最大值 private static void maxIf2() { int a = (int) ( ...