首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

Rust 中 *、&、mut、&mut、ref、ref mut 的用法和区别

编程知识
2024年07月25日 14:25

Rust 中 *、&、mut、&mut、ref、ref mut 的用法和区别

Rust 中,*refmut&ref mut 是用于处理引用、解引用和可变性的关键字和操作符,它们在不同的上下文中有不同的用法。

一、* 解引用

* 属于操作符

1. 作用

用于解引用指针或引用,以访问其指向的值。
通过解引用,可以从指针或引用中获取实际的值。

2. 用法

2.1. 解引用不可变引用

fn main() {
	let x = 5;
	let y = &x; // y 是对 x 的不可变引用
	println!("y: {}", *y); // 通过解引用 y 获取 x 的值,输出: y: 5
}

2.2. 解引用可变引用

fn main() {
	let mut x = 10;
    let y = &mut x; // y 是对 x 的可变引用
    *y += 5; // 通过解引用 y 修改 x 的值
    println!("x: {}", x); // 输出: x: 15
}

2.3. 解引用指针

fn main() {
	let x = 42;
    let y = &x as *const i32; // 创建不可变裸指针
    unsafe {
        println!("y: {}", *y); // 解引用不可变裸指针
    }
	
	let x = Box::new(10); // Box 智能指针
    println!("x: {}", *x); // 解引用 Box,获取其值,输出: x: 10
}

二、& 借用引用

& 也是操作符

1. 作用

创建一个值的不可变引用,允许读而不获取所有权,该值在引用期间是只读的。

2. 用法

2.1. 不可变引用

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

2.2. 函数中的借用

fn print_value(x: &i32) {
    println!("Value: {}", x);
}

fn main() {
    let a = 10;
    print_value(&a); // 传递 a 的不可变引用
}

2.3. match 中使用

fn main() {
	let reference = &4;
    match reference {
        &val => println!("Got a value via destructuring: {:?}", val),
    }
}

2.4. 结构体中使用

struct Point<'a> {
    x: &'a i32,
    y: &'a i32,
}
fn main() {
    let x = 10;
    let y = 20;
    let point = Point { x: &x, y: &y }; // 使用引用初始化结构体字段
    println!("Point: ({}, {})", point.x, point.y); // 输出: Point: (10, 20)
}

2.5. 集合中使用

fn main() {
    let vec = vec![1, 2, 3];
    for val in &vec {
        println!("Value: {}", val); // 输出: 1, 2, 3
    }
}

2.6. 切片中使用

fn main() {
    let s = String::from("hello");
    let slice = &s[0..2]; // 创建字符串切片
    println!("Slice: {}", slice); // 输出: Slice: he
}

三、mut 可变

mut 是一个关键字

1. 作用

声明一个变量或引用为可变的,可以修改其值。

2. 用法

2.1. 可变变量

fn main() {
    let mut x = 5; // x 是可变的
    x += 1;
    println!("x: {}", x); // 输出: x: 6
}

2.2. 函数中可变参数

fn increment(mut num: i32) -> i32 {
    num += 1;
    num
}

2.3. 可变引用

fn main() {
    let mut x = 5;
    let y = &mut x;
    *y += 1;
    println!("{}", x); // 输出 6
}

2.4. 可变结构体

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

2.5. 可变元组

let mut tuple = (5, 10);
tuple.0 = 15;

2.6. match 中使用

match Some(10) {
    Some(mut value) => {
        value += 1;
        println!("{}", value); // 输出 11
    }
    None => {},
}

2.7. 集合中使用

let mut vec = vec![1, 2, 3];
for num in &mut vec {
    *num += 1;
}
println!("{:?}", vec);

四、&mut 可变借用引用

&mut 既不属于操作符也不属于关键字

1. 作用

创建一个值的可变引用,允许修改值而不获取所有权。

2. 用法

2.1. 可变引用

fn main() {
    let mut x = 10;
    {
        let y = &mut x; // y 是对 x 的可变引用
        *y += 5; // 修改 x 的值
    } // y 的生命周期结束,此时 x 的可变借用结束
    println!("x: {}", x); // 输出: x: 15
}

2.2. 函数中的可变引用

fn add_one(x: &mut i32) {
    *x += 1;
}

fn main() {
    let mut a = 10;
    add_one(&mut a); // 传递 a 的可变引用
    println!("a: {}", a); // 输出: a: 11
}

2.3. 结构体中的可变引用

struct Point<'a> {
    x: &'a mut i32,
    y: &'a mut i32,
}
fn main() {
    let mut x = 10;
    let mut y = 20;
    let point = Point { x: &mut x, y: &mut y }; // 使用可变引用初始化结构体字段
    *point.x += 1;
    *point.y += 1;
    println!("Point: ({}, {})", point.x, point.y); // 输出: Point: (11, 21)
}

2.4. 集合中的可变引用

fn main() {
    let mut vec = vec![1, 2, 3];
    for val in &mut vec {
        *val += 1; // 修改集合中的元素
    }
    println!("{:?}", vec); // 输出: [2, 3, 4]
}

2.5. match 中使用

fn main() {
    let mut pair = (10, 20);
    match pair {
        (ref mut x, ref mut y) => {
            *x += 1;
            *y += 1;
            println!("x: {}, y: {}", x, y); // 输出: x: 11, y: 21
        },
    }
}

2.6. 结构体中使用

struct Counter {
    value: i32,
}
impl Counter {
    fn increment(&mut self) {
        self.value += 1;
    }
}
fn main() {
    let mut counter = Counter { value: 0 };
    counter.increment(); // 使用可变引用调用方法
    println!("Counter value: {}", counter.value); // 输出: Counter value: 1
}

五、ref 模式匹配中创建引用

ref 属于关键字

1. 作用

在模式匹配中借用值的不可变引用,而不是获取所有权。

2. 用法

2.1. 元组中使用

fn main() {
    let tuple = (1, 2);
    let (ref x, ref y) = tuple; // x 和 y 是对 tuple 中元素的不可变引用
    println!("x: {}, y: {}", x, y); // 输出: x: 1, y: 2
}

2.2. match 中使用

fn main() {
    let pair = (10, 20);
    match pair {
        (ref x, ref y) => {
            println!("x: {}, y: {}", x, y); // x 和 y 是 pair 元素的不可变引用
        }
    }
}

2.3. if let / while let 中使用

// if let
fn main() {
    let some_value = Some(42);
    if let Some(ref x) = some_value {
        println!("Found a value: {}", x); // x 是 some_value 的不可变引用
    }
}
// while let
fn main() {
    let mut stack = vec![1, 2, 3];
    while let Some(ref x) = stack.pop() {
        println!("Popped: {}", x); // x 是 stack 中最后一个元素的不可变引用
    }
}

2.4. 函数中使用

fn print_ref((ref x, ref y): &(i32, i32)) {
    println!("x: {}, y: {}", x, y); // x 和 y 是元组元素的不可变引用
}
fn main() {
    let pair = (10, 20);
    print_ref(&pair); // 传递 pair 的引用
}

2.5. for 循环中使用

fn main() {
    let vec = vec![1, 2, 3];
    for ref x in &vec {
        println!("x: {}", x); // x 是 vec 中元素的不可变引用
    }
}

六、ref mut 模式匹配中创建可变引用

ref mut 属于关键字

1. 作用

在模式匹配中借用值的可变引用,允许修改该值。

2. 用法

2.1. match 中使用

fn main() {
    let mut pair = (10, 20);
    match pair {
        (ref mut x, ref mut y) => {
            *x += 1;
            *y += 1;
            println!("x: {}, y: {}", x, y); // 输出: x: 11, y: 21
        }
    }
    // pair 的值已经被修改
}

2.2. if let / while let 中使用

fn main() {
    let mut some_value = Some(42);
    if let Some(ref mut x) = some_value {
        *x += 1;
        println!("Found a value: {}", x); // 输出: Found a value: 43
    }
}
fn main() {
    let mut stack = vec![1, 2, 3];
    while let Some(ref mut x) = stack.pop() {
        *x += 1;
        println!("Popped: {}", x); // 输出: Popped: 4, Popped: 3, Popped: 2
    }
}

2.3. 函数中使用

fn increment_tuple((ref mut x, ref mut y): &mut (i32, i32)) {
    *x += 1;
    *y += 1;
}

fn main() {
    let mut pair = (10, 20);
    increment_tuple(&mut pair); // 传递 pair 的可变引用
    println!("pair: {:?}", pair); // 输出: pair: (11, 21)
}

2.4. 解构赋值

fn main() {
    let mut pair = (10, 20);
    let (ref mut x, ref mut y) = pair;
    *x += 1;
    *y += 1;
    println!("x: {}, y: {}", x, y); // 输出: x: 11, y: 21
    println!("{:?}", pair); // (11, 21)
}

七、总结

  • *:解引用操作符,用于访问指针或引用指向的值的类型。
  • &:借用操作符,用于创建不可变引用的类型,允许只读访问。
  • mut:关键字,用于声明可变变量或参数的类型,允许其值被修改。
  • &mut:借用操作符,用于创建可变引用的类型,允许读写访问。
  • ref:模式匹配中的关键字,用于创建不可变引用的类型,避免所有权转移。
  • ref mut:模式匹配中的关键字,用于创建可变引用的类型,允许修改引用的值。
From:https://www.cnblogs.com/risheng/p/18323252
本文地址: http://shuzixingkong.net/article/422
0评论
提交 加载更多评论
其他文章 整段 html实现其中的每一个 a 标签跨域下载操作 window.URL.createObjectURL(blob)
window.URL.createObjectURL(blob) a 标签下载问题,通常在 a 标签中加上download属性,就可完成对href属性链接文件的下载,但仅仅是限于同源文件,如果是非同源,download 属性就会失效 第一种情况,单独的一个标签实现下载,可以使用 span 标签+cl
Cython与C函数的结合
这篇文章介绍了Python-Cython-C三种语言的简单耦合,以Cython为中间接口,实现Python数据传到C语言的后端执行相关计算。这就相当于可以在Python中调用C语言中的指针功能来进行跨维度的数组运算,至于性能依然存在优化空间,这里仅仅做一个简单的功能演示。
Nuxt.js 环境变量配置与使用
title: Nuxt.js 环境变量配置与使用 date: 2024/7/25 updated: 2024/7/25 author: cmdragon excerpt: 摘要:“该文探讨了Nuxt.js框架下环境变量配置的详细过程,涉及.env文件配置、运行时访问、安全性考量、在不同场景下的实践(
Nuxt.js 环境变量配置与使用 Nuxt.js 环境变量配置与使用
【最新最热】几何朗兰兹猜想终获破解!跨越30年研究,800余页证明论文问世,中国学者陈麟卓越贡献!
历经三十余载的潜心研究,九位杰出的数学家携手跨越了学术的崇山峻岭,通过五篇累计超过八百页的深邃论文,终于迎来了数学史上的一大盛事——几何朗兰兹猜想的壮丽证明! 这一里程碑式的成就,正是朗兰兹纲领几何化版本的璀璨绽放。朗兰兹纲领,作为现代数学研究的璀璨明珠,被誉为“数学的大统一理论”,它深刻地揭示了数
【最新最热】几何朗兰兹猜想终获破解!跨越30年研究,800余页证明论文问世,中国学者陈麟卓越贡献! 【最新最热】几何朗兰兹猜想终获破解!跨越30年研究,800余页证明论文问世,中国学者陈麟卓越贡献! 【最新最热】几何朗兰兹猜想终获破解!跨越30年研究,800余页证明论文问世,中国学者陈麟卓越贡献!
LeetCode513. 找树左下角的值
题目链接:https://leetcode.cn/problems/find-bottom-left-tree-value/description/ 题目叙述: 给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1: 输入: roo
LeetCode513. 找树左下角的值 LeetCode513. 找树左下角的值
三星app移植修复(app反编译修改)
工具: apktool ADT 命令: 反编译 java -jar apktool.jar d test.apk 重打包 java -jar apktool.jar b test 签名使用ADT smail语言粗略理解(其实对于修改来说, 大概熟悉就就ok) 类定义 .class public Lc
三星app移植修复(app反编译修改) 三星app移植修复(app反编译修改) 三星app移植修复(app反编译修改)
深入探讨Spring Boot中的参数传递
深入探讨Spring Boot中的参数传递 在Spring Boot开发中,参数传递是一个非常常见且重要的操作。无论是处理HTTP请求,还是在方法之间传递数据,理解和掌握参数传递的各种方式都能让我们的代码更加简洁和高效。今天,我们就来深入探讨一下Spring Boot中的参数传递。 1. 基础知识:
RIME:用交叉熵 loss 大小分辨 preference 是否正确 + 内在奖励预训练 reward model
① 假设正确样本的 CELoss 上限是 ρ,可推出错误样本相对 P_ψ(x) 分布的 KL 散度上限,从而筛出可信样本、翻转不可信样本;② 用归一化到 (-1,1) 的 intrinsic reward 预训练 reward model。