【Rust练习】7.引用与借用

news2024/11/20 13:23:18

练习题来自:https://practice-zh.course.rs/ownership/borrowing.html

1

fn main() {
   let x = 5;
   // 填写空白处
   let p = __;

   println!("x 的内存地址是 {:p}", p); // output: 0x16fa3ac84
}

其实Rust的借用,就类似C++的指针和引用,如果你有C++的基础,这道题就很好理解——取p的地址。

fn main() {
    let x = 5;
    // 填写空白处
    let p = &x;

    println!("x 的内存地址是 {:p}", p); // output: 0x16fa3ac84
}

运行结果

2

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

    // 只能修改以下行
    assert_eq!(5, y);
}

对熟悉C++的同学来说,这道题也很好理解,&用于取地址,而*用于从地址取数据。

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

    // 只能修改以下行
    assert_eq!(5, *y);
}

3

// 修复错误
fn main() {
    let mut s = String::from("hello, ");

    borrow_object(s)
}

fn borrow_object(s: &String) {}

函数入参应该是String的借用(指针),而不是String本身。

fn main() {
    let mut s = String::from("hello, ");

    borrow_object(&s)
}

fn borrow_object(s: &String) {}

4

// 修复错误
fn main() {
    let mut s = String::from("hello, ");

    push_str(s)
}

fn push_str(s: &mut String) {
    s.push_str("world")
}

和上面一样,不多解释了。

fn main() {
    let mut s = String::from("hello, ");

    push_str(&mut s)
}

fn push_str(s: &mut String) {
    s.push_str("world")
}

5

fn main() {
    let mut s = String::from("hello, ");

    // 填写空白处,让代码工作
    let p = __;
    
    p.push_str("world");
}

应该是对s的可变引用。

fn main() {
    let mut s = String::from("hello, ");

    // 填写空白处,让代码工作
    let p = &mut s;

    p.push_str("world");
}

6

fn main() {
    let c = '中';

    let r1 = &c;
    // 填写空白处,但是不要修改其它行的代码
    let __ r2 = c;

    assert_eq!(*r1, *r2);
    
    // 判断两个内存地址的字符串是否相等
    assert_eq!(get_addr(r1),get_addr(r2));
}

// 获取传入引用的内存地址的字符串形式
fn get_addr(r: &char) -> String {
    format!("{:p}", r)
}

ref x = p,就是x = &p

fn main() {
    let c = '中';

    let r1 = &c;
    // 填写空白处,但是不要修改其它行的代码
    let ref r2 = c;

    assert_eq!(*r1, *r2);
    
    // 判断两个内存地址的字符串是否相等
    assert_eq!(get_addr(r1),get_addr(r2));
}

// 获取传入引用的内存地址的字符串形式
fn get_addr(r: &char) -> String {
    format!("{:p}", r)
}

7

// 移除代码某个部分,让它工作
// 你不能移除整行的代码!
fn main() {
    let mut s = String::from("hello");

    let r1 = &mut s;
    let r2 = &mut s;

    println!("{}, {}", r1, r2);
}

可变引用同时只能存在一个,因此都改成不可变即可(这样变量的mut就没意义了)。

fn main() {
    let mut s = String::from("hello");

    let r1 = & s;
    let r2 = & s;

    println!("{}, {}", r1, r2);
}

8

fn main() {
    // 通过修改下面一行代码来修复错误
    let  s = String::from("hello, ");

    borrow_object(&mut s)
}

fn borrow_object(s: &mut String) {}

类似于C++里对变量声明const和指针的关系一样(现在应该用constexpr了)。常量只能使用常量指针,比如如下代码:

const int num = 1;

使用如下指针是不能指向num的:

int *const p = #//p不可被更改,但p指向的数据,也就是num可以更改。这和num是const矛盾。此行代码会编译失败。

正确的写法是:

int const *p = #//虽然p本身可以被修改(比如可以指向别的数据),但p所指向的数据不可更改。

C++中的引用类似,只不过引用本身不是对象,所以没有改变这个概念,const 引用才能引用常量。
Rust也一样,s不可变,那就不能有任何一个可变的引用借用s

fn main() {
    // 通过修改下面一行代码来修复错误
    let mut s = String::from("hello, ");

    borrow_object(&mut s)
}

fn borrow_object(s: &mut String) {}

9

// 下面的代码没有任何错误
fn main() {
    let mut s = String::from("hello, ");

    borrow_object(&s);
    
    s.push_str("world");
}

fn borrow_object(s: &String) {}

同上,不可变的引用指向可变的变量是可以的,但是这个引用不能拿来改变变量(即使变量可变)

10

// 注释掉一行代码让它工作
fn main() {
    let mut s = String::from("hello, ");

    let r1 = &mut s;
    r1.push_str("world");
    let r2 = &mut s;
    r2.push_str("!");
    
    println!("{}",r1);
}

r1作为引用的作用域直到自身最后一次出现为止,因此,r2刚好在r1的作用域内,触发了不能同时存在两个可变引用的问题。注释掉最后一行,让r1的作用域在第一次push就结束,就不会出现这个问题了。

fn main() {
    let mut s = String::from("hello, ");

    let r1 = &mut s;
    r1.push_str("world");
    let r2 = &mut s;
    r2.push_str("!");
    
    // println!("{}",r1);
}

11

fn main() {
    let mut s = String::from("hello, ");

    let r1 = &mut s;
    let r2 = &mut s;

    // 在下面增加一行代码人为制造编译错误:cannot borrow `s` as mutable more than once at a time
    // 你不能同时使用 r1 和 r2
}

同上。

fn main() {
    let mut s = String::from("hello, ");

    let r1 = &mut s;
    let r2 = &mut s;

    r1.push_str("string");

    // 在下面增加一行代码人为制造编译错误:cannot borrow `s` as mutable more than once at a time
    // 你不能同时使用 r1 和 r2
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1978956.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

面对挫折和恶语 良好心态非常重要

你等年纪轻轻一遇挫折,便松散懈怠,日后怎成大器? 虽称满腹经纶,却是鸡肠鼠肚,连几句恶语都容它不下,你等要记住,为人者,有大度成大器也!夫处世之道,即应变之术, 岂可偏执一端? 【迷茫时,不妨听听司马仲达的人生格言】https://www.bilibili.com/video/BV1JF411i7…

React--》掌握styled-components重塑React样式管理

想象一下,如果你的React组件不仅能自描述其逻辑,还能直接声明自己的样式,这种“所见即所得”的编程体验是不是让人心动不已?styled-components正是这样一把钥匙,它彻底颠覆了我们对React样式管理的传统认知&#xff0c…

Python 中单例模式实现的几种方式

在设计模式中,单例模式是经常被提及和使用的一种模式。它保证一个类只有一个实例,并提供全局访问点。在Python中,有多种实现单例模式的方法。那么,如何选择合适的方法来实现单例模式呢? 单例模式在Python中的几种实现方…

软件设计师笔记-网络基础知识

计算机网络的发展 计算机网络(计算机技术通信技术)的发展是一个逐步演进的过程,从简单的具有通信功能的单机系统,到复杂的以局域网及因特网为支撑环境的分布式计算机系统,这一历程经历了多个关键阶段: #me…

大模型是否潜在地进行多跳推理?

人工智能咨询培训老师叶梓 转载标明出处 以往的研究表明,基于Transformer的LLMs能够在参数中存储和检索事实信息,以完成简单提示,例如“Stevie Wonder的母亲是谁”。此外,当必要信息明确给出时,LLMs表现出了显著的上下…

JS优化了4个自定义倒计时

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><title>4个自定义倒计时</title><style>* {margin: 0;padding: 0;box-sizing: border-box;user-select: none;body {background: #0b1b2c;}}hea…

(javaweb)maven--Java项目的构建工具

目录 一.Maven概述 二.Idea导入maven项目 三.maven核心功能--依赖管理 四.依赖管理--依赖传递 五.依赖管理--依赖范围 六.依赖管理--生命周期 一.Maven概述 1.管理和构建Java项目的工具 2.Apache开源&#xff08;源代码开放&#xff09; 3. 4. Maven核心配置文件&#xff…

解题 - 左旋字符串的三种解法(思路)

文章目录 前言&#xff1a; 题干&#xff1a; 解题思路&#xff1a; 思路一&#xff1a; 思路二&#xff1a; 思路三&#xff1a; 小结 前言&#xff1a; 路漫漫其修远兮&#xff0c;吾将上下而求索。 题干&#xff1a; 解题思路&#xff1a; 创建变量k &#xff0c;用…

【知识专栏丨python数分实战】关于电商零售客户细分数据分析及可视化

今天这篇文章将给大家介绍关于电商零售客户细分数据分析及可视化的案例分析。 01 数据整理 导入数据 import pandas as pdimport numpy as npfrom pyecharts.charts import *import pyecharts.options as opts import warningswarnings.filterwarnings(ignore) 数据读取及预…

shell的基础介绍

文章目录 shell数组读取数组关联数组获取数组的长度 Shell运算符算术运算符关系运算符布尔运算符逻辑运算符字符串运算符文件测试运算符 Shell echo命令1.显示普通字符串2.显示转义字符3.显示变量4.显示换行5.显示不换行6.显示结果定向至文件7.原样输出字符串&#xff0c;不进行…

Macbook上运行Windows系统工具Parallels Desktop19

亲爱的笔记本小能手们&#xff0c;你们是否也有这样的困扰&#xff1a;在Macbook上运行Windows系统&#xff0c;却发现虚拟机软件要么卡顿&#xff0c;要么操作复杂&#xff1f;别急&#xff0c;今天就给你们种草一款神器——Parallels Desktop 19。 Parallels Desktop最新绿色…

无人机工程师技术高级证书详解

随着无人机技术的飞速发展&#xff0c;其在航拍、农业、测绘、救援、物流等多个领域的应用日益广泛&#xff0c;对无人机工程师的专业技能与综合素质提出了更高要求。无人机工程师技术高级证书&#xff0c;作为对无人机领域高级工程师专业技能的权威认证&#xff0c;不仅是对个…

QT网络编程

Qt 给用户提供了网络编程的接口&#xff0c;包括TCP、UDP、HTTP三种协议的API以及各种类&#xff0c;可以了解一下。 而在 QT 中想要使用网络编程&#xff0c;必须在pro文件中添加 network 模块&#xff0c;否则无法包含网络编程所需的头文件。 UDP UDP是传输层的协议&#…

Animate软件基础:在时间轴中标识动画

FlashASer&#xff1a;AdobeAnimate2021软件零基础入门教程https://zhuanlan.zhihu.com/p/633230084 FlashASer&#xff1a;实用的各种Adobe Animate软件教程https://zhuanlan.zhihu.com/p/675680471 FlashASer&#xff1a;Animate教程及作品源文件https://zhuanlan.zhihu.co…

实战项目导航

目录 1.AI毕设生成器&#xff08;完善中&#xff09;2.计算机设计大赛案例3.c迷宫游戏4.python学生管理系统教学关注持续更新哦 1.AI毕设生成器&#xff08;完善中&#xff09; 文章链接 &#x1f680; 一键启航&#xff0c;编码从未如此简单&#xff01; 探索Python毕业设计生…

vulnhub之serial

这次我们来做这个靶场 项目地址https://download.vulnhub.com/serial/serial.zip 使用vm新建虚拟机 以下为注意事项 第一步&#xff0c;收集资产 扫描靶场ip netdiscover -i eth0 -r 192.168.177.0/24 抓个包 扫描目录 看到了cookie中有一个user Tzo0OiJVc2VyIjoyOntzOj…

【Golang 面试 - 进阶题】每日 3 题(十八)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/UWz06 &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏…

算法:BFS 解决拓扑排序

目录 拓扑排序 题目一&#xff1a;课程表 题目二&#xff1a;课程表II 题目三&#xff1a;火星词典 拓扑排序 有向无环图(DAG图) 有向无环图也就是有几个点&#xff0c;每个点之间的线段都是有向的&#xff0c;且任意拿出来几个点&#xff0c;都是无环的&#xff0c;这里…

Adaboost集成学习 | Matlab实现基于ELM-Adaboost极限学习机结合Adaboost集成学习故障诊断

目录 效果一览基本介绍程序设计参考资料效果一览 基本介绍 Adaboost集成学习 | Matlab实现基于ELM-Adaboost极限学习机结合Adaboost集成学习故障诊断 ELM(Extreme Learning Machine)和 Adaboost 都是机器学习领域中常见的算法。ELM 是一种单隐层前馈神经网络,具有快速训练、…