zoukankan      html  css  js  c++  java
  • 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的内部。从这里可以
    看出每一个函数是一个自治的。

  • 相关阅读:
    C# 根据二级栏目Id查询出所属文章的信息列表
    C#网站首页制作MVC
    C#Mvc退出登录
    C#Mvc修改密码
    C#网站开发之内容页Content
    C#Mvc登录功能
    Linux命令——shell
    学习笔记cisco常用命令
    性能相关术语
    Linux命令(一)
  • 原文地址:https://www.cnblogs.com/Davirain/p/13639193.html
Copyright © 2011-2022 走看看