首页 > 其他分享 >RUST的引用和借用

RUST的引用和借用

时间:2024-10-05 16:33:13浏览次数:8  
标签:作用域 y1 let 引用 借用 println y2 RUST

    上一篇博客说到,移动是转交所有权,而克隆(Copy和Clone)是获得一个和旧值相同的新值的所有权)。

    那么如果我们想不转交所有权又对变量的值进行读取和修改(比如方法的传参问题,会改变所有权,即移动;或者读取和修改的不是原变量的值,即克隆),应该怎么做?

    RUST提供了引用和借用的机制。常规引用是一个指针类型,指向了对象存储的内存地址(和C++的指针比较像);获取变量的引用,则叫做借用。

    引用允许我们获得对值的使用权,但不是所有权。RUST中使用&获得变量的引用。

    C++需要通过*来访问指针指向的值,类似的,RUST也需要使用*来解引用,访问引用指向的值。不过RUST提供了自动解引用功能,大部分时候不需要显式解引用(一些情况如方法传参需要非引用的形参时还是要解引用的)。

struct Point {
    x: i32,
    y: i32,
}
fn main() {
    let p = Point { x: 10, y: 20 };
    println!("({}, {})", p.x, p.y);   //输出(10, 20)

    let q=&p;

    println!("({}, {})", (*q).x, (*q).y);  //输出(10, 20)
    println!("({}, {})", q.x, q.y);  //输出(10, 20)
}

    刚才说,引用允许获得对变量的使用权。

fn main() {
    let x = 5;
    let y=&x;   //y是x的引用
    println!("y: {}", y);  //输出y: 5
    println!("x: {}", x);  //输出x: 5
}

    但是上述代码中y只能读取x的值,而不能修改x的值,只实现了我们目标的一半。这又得说到不可变引用和可变引用的概念。

    不可变引用,即只能读取变量的值,不能对值进行修改(相当于C++中的const T*)。上面的例子中y就是一个不可变引用。

    可变引用,即既能读取变量的值,又能对值进行修改。

fn main() {
    let mut x = 5;
    let y=&mut x;

    (*y)+=1;

    println!("y: {}", y);  //输出y: 6
    println!("x: {}", x);  //输出x: 6
}

    上述代码中y是x的一个可变引用。使用&mut获取变量的可变引用。需要注意的是,被获取可变引用的变量必须是可变(mut)的。

    看到这里大家可能会想,这和C++的指针有啥区别吗?

    其实还是有的。在RUST中,引用有两条比较重要的限制:

1. 在相同作用域,同一个变量的可变引用只能存在一个。
2. 相同变量的可变引用和不可变引用不能同时存在。

    为什么要有这两条限制呢?原因是可以使Rust在编译期避免数据竞争。而数据竞争会导致未定义行为,这种行为很可能超出我们的预期,难以在运行时追踪,并且难以诊断和修复。
    先看第一条限制。

fn main() {
    //会报错,y1和y2的作用域重叠了
    let mut x = 5;
    let y1=&mut x;
    let y2=&mut x;

    println!("y1: {}", y1);//y1的作用域一直到这里结束
    println!("y2: {}", y2);  //y2的作用域一直到这里结束
}

    再看第二条限制。

fn main() {
    let mut x = 5;
    let y1= &x;
    let y2=&x;
    let y3=&mut x;  //会报错,因为已经有不可变引用了

    println!("y1: {}", y1);  //y1作用域到这里结束
    println!("y2: {}", y2);  //y2作用域到这里结束
    println!("y3: {}", y3); ////y3作用域到这里结束
}

    再说说引用的作用域。引用的作用域从引用的定义开始,到引用的最后一次使用结束。

fn main() {
    let mut x = 5;

    let y1= &x;  //y1的作用域在这里就结束了
    let y2=&x;   //y2的作用域在这里就结束了
    let y3=&mut x;  //不会报错
}

    在上述例子中,x的可变引用和不可变引用不会同时存在,所以不会报错。

标签:作用域,y1,let,引用,借用,println,y2,RUST
From: https://www.cnblogs.com/nomore007/p/18447842

相关文章

  • 谷歌:过渡到 Rust 使得 Android 漏洞大幅下降
    谷歌:过渡到Rust使得Android漏洞大幅下降来源:OSCHINA编辑: 白开水不加糖2024-09-2810:54:58 6谷歌在最新的一篇文章中指出,内存安全问题导致的漏洞百分比与新代码使用的开发语言密切相关。而随着其将开发转向内存安全语言,Android内存安全漏洞的百分比已经......
  • C#基础-值类型引用类型&类与结构体
             通俗的来讲(仅代表个人理解),可以将数据区存储看成一个书架(栈)和一座图书馆(堆)堆栈内存是动态的,还有静态区域(程序运行编译时内存就固定的)。书架上存放这一些值类型、一些对象的引用、方法参数、局部变量等 。而图书馆中存放着较为复杂的、有特殊功能的、......
  • PbootCMS模板怎么嵌套引用其他模版文件
    模板文件嵌套引用是一种常见的做法,可以提高代码的复用性和维护性。在PbootCMS中,可以使用 {include} 标签来引用其他模板文件。下面详细介绍如何进行模板文件嵌套引用,并给出具体示例。模板文件嵌套引用在PbootCMS中,使用 {include} 标签来引用其他模板文件。语法如下:ht......
  • C语言中指针解引用
    在32位的操作系统中,指针占据4个字节。在64位的操作系统中,指针占据8个字节。以下程序都是在32位操作系统中运行的。1.指针解引用程序运行结果为12345600进入调试,可以看到变量a在内存占4个字节,a的地址为0x008FF794,在内存中的存储方式为小端存储方式。当程序走完*p=0这一行......
  • C++之operator(附加返回引用的一些内容)
    在C++中,操作符重载允许你为自定义类型定义操作符的行为,使其可以像内置类型一样使用。通过定义operator函数,你可以指定操作符如何处理对象。基本语法ReturnTypeoperatorOp(Parameters){//实现}示例加法操作符重载#include<iostream>classPoint{public......
  • RUST所有权相关问题
    先介绍一下RUST的所有权规则:1.Rust中的每一个值都有一个所有者(owner)。2.值在任一时刻有且只有一个所有者。3.当所有者(变量)离开作用域,这个值将被丢弃。变量与数据交互的方式包括两种:移动和克隆。移动就是转交值的所有权,如letx=y(x的类型未实现Copytrait),x失去了值的所有......
  • rustling学习随笔
    序言rustling是一个关于rust的练习题的项目.可以帮助大家通过完成一个项目的方式练习rust的语法,我认为对于补充我rust现学现卖过程中的情况很有帮助.下边是GPT对它的介绍:Rustling是专为那些想要学习Rust编程语言的人设计的一个交互式练习集合。无论你是编程新手还是有经......
  • Salesforce AI Specialist篇之 Einstein Trust Layer
    本篇参考:https://trailhead.salesforce.com/content/learn/trails/drive-productivity-with-einstein-aihttps://help.salesforce.com/s/articleView?id=sf.generative_ai_trust_layer.htm&type=5https://blog.salesforceairesearch.com/meet-salesforces-trusted-ai-prin......
  • [rCore学习笔记 028] Rust 中的动态内存分配
    引言想起我们之前在学习C的时候,总是提到malloc,总是提起,使用malloc现场申请的内存是属于堆,而直接定义的变量内存属于栈.还记得当初学习STM32的时候CubeIDE要设置stack和heap的大小.但是我们要记得,这么好用的功能,实际上是操作系统在负重前行.那么为了实现动态内存分配功......
  • vite5+tauri2.0+vue3+rust桌面exe聊天系统演示
    Tauri2.0-Vue3Chat:自研基于tauri2.0+rust+vue3setup+pinia2+element-plus等技术搭建的一款高颜值仿QQ/微信客户端聊天EXE软件。整个聊天窗口采用自定义无边框透明圆角阴影UI模式。tauri2.0-vitechat:自研vue3+tauri2+element-plus客户端聊天程序项目特点整体窗口采......