rust踩雷笔记(1)——切片传参和解引用赋值

这篇具有很好参考价值的文章主要介绍了rust踩雷笔记(1)——切片传参和解引用赋值。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

最近学习rust,网上资料还是很有限,做题遇到的问题,有时需要自己试验。把自己做题过程遇到的问题,和试验的结论,做一些简单记录。

阅读下列文字和代码

用切片(的引用)做参数要非常小心,切片中的某个元素直接用=赋值,用的是copy方式而不是所有权转移(实践证明)。
如果要用切片中的值赋值,那么可以对切片元素clone(需要元素类型实现Clone trait),
或者限制切片元素类型为实现了copy trait。String没有实现Copytrait,实现了Clone trait
let l: String = *y;(y是&String),这种解引用再用=赋值,走的也是copy方式,
就会报错(String没实现copy trait)
给类型上加#[derive(Copy)]可以添加Copy特征,Copy特征有自己默认实现的代码,
这个类型就可以调用它们,也可以自己重写方法

fn main() {
    let mut x = String::from("hello");
    let y = &x;
    let z = y;
    println!("{}", *y);
    // let l: String = *y;     // 会报错。通过报错信息可知,解引用再用=赋值,是copy操作
    // 直接将String本身用=赋值,是转移所有权;
    // 将String本身的引用,解引用后用=赋值,是copy操作,
    // String没有实现copy特性,所以会报错(上一行)
    let l = x;
}

fn largest2(s: &[String]) -> String {
    // 下面错误,原因是会发生所有权转移,但是s是一个切片(的引用),
    // 切片:[String, String, ... , String],
    // 如果其中某个元素发生了所有权转移,是不被允许的,所以这里只能通过拷贝
    // 但是String没有实现copy trait,所以会报错。正确做法是用clone()
    // let mut res: String = s[0];
    let mut res: String = s[0].clone();
    res
}

/*
重大发现,这个泛型如果不限制它实现copy特征,那么发生传值的时候,
比如我写let x = list[0],注意list是这个切片首地址,list[0]就是切片中首元素,
它是T类型的,这种赋值方式会copy一份给x绑定,如果T没实现copy trait怎么办?
所以要限定T的范围,这里限定T为实现了Copy特征的类型
*/
fn largest<T: std::cmp::PartialOrd + Copy>(list: &[T]) -> T {
    let mut res = &list[0];
    for i in list.iter() {
        if *i > *res {
            res = i;
        }
    }
    *res    // res是T类型的引用,这种返回是用&T
}

// 如果要用clone(),得确保类型实现了Clone
fn largest1<T: std::cmp::PartialOrd + Clone>(list: &[T]) -> T {
    let mut res = list[0].clone();
    for i in list.clone() {
        if *i > res {
            res = i.clone();
        }
    }
    res
}
结构体赋值的例子

这个是从rust圣经上摘录的

struct User {
    active: bool,
    username: String,
    email: String,
    sign_in_count: u64,
}

我们创建了一个user1,代码略,然后用user1更新user2:

  let user2 = User {
        email: String::from("another@example.com"),
        ..user1
    };

这里除了email是新创建,其他都是和user1一样。其中username字段进行了所有权转移,原因:

实现了 Copy 特征的类型无需所有权转移,可以直接在赋值时进行 数据拷贝,其中 bool 和 u64 类型就实现了 Copy 特征(来源rust圣经)

由于user1中username的所有权转移给了user2,user1之后就不能使用了。但是通过user1.active、user1.email、user1.sign_in_count可以使用user1中没有失效的属性。文章来源地址https://www.toymoban.com/news/detail-651083.html

到了这里,关于rust踩雷笔记(1)——切片传参和解引用赋值的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Rust切片

    在Rust中,切片(Slice)是一种不持有所有权的数据类型,它允许我们引用字符串中的一部分内容而不需要拷贝整个字符串。切片提供了对序列的局部访问,是字符串操作中非常灵活的工具。本篇博客将介绍Rust的切片概念,以及在使用切片时的注意事项。 在Rust中,字符串切片

    2024年02月20日
    浏览(25)
  • 30天拿下Rust之切片

    概述         在Rust中,切片是一种非常重要的引用类型。它允许你安全地引用一段连续内存中的数据,而不需要拥有这些数据的所有权。切片不包含分配的内存空间,它仅仅是一个指向数据开始位置和长度的数据结构。切片是对数组的一个连续引用,它提供了一种方便、

    2024年03月13日
    浏览(53)
  • 【Rust 基础篇】Rust 解引用多态

    在 Rust 中,解引用多态(Deref Coercion)是一种特性,它允许自动进行类型转换,将实现了 Deref trait 的类型转换为目标类型的引用。通过解引用多态,我们可以更方便地使用不同类型的智能指针和引用。 本篇博客将详细介绍 Rust 中解引用多态的使用方法和相关概念,以及它在代

    2024年02月16日
    浏览(36)
  • 【Rust 基础篇】Rust 引用循环:解析和避免

    在 Rust 中,引用循环是指两个或多个对象之间相互引用,形成一个循环链。这种情况下,对象之间的引用计数永远不会变为零,导致内存泄漏和资源泄漏。本篇博客将详细介绍 Rust 引用循环的概念、问题和解决方案,并通过代码示例演示如何避免引用循环。 引用循环在 Rust

    2024年02月17日
    浏览(37)
  • Rust - 可变引用和悬垂引用

    在上一篇文章中,我们提到了 借用 的概念,将获取引用作为函数参数称为  借用 ( borrowing ),通常情况下,我们无法修改 借来的变量 ,但是可以通过 可变引用 实现修改 借来的变量 。代码示例如下: 要想实现修改 借来的变量 就必须将  s 改为  mut 。然后必须创建一个

    2024年01月22日
    浏览(39)
  • rust 引用怎么用

    文章会通过三个例子来了解 rust 所有权的机制,都是从应用的角度来说明,rust 所有权底层是如何实现会在后续的内容中介绍。 理解 RUST 所有权规则: RUST 中的每个值都有一个对应的变量作为它的所有者 同一时间内,值有且仅有一个所有者 当所有者离开自己的作用域时,它

    2024年02月16日
    浏览(48)
  • Rust-解引用

    “解引用”(Deref)是“取引用”(Ref)的反操作。取引用,我们有、mut等操作符,对应的,解引用,我们有 操作符,跟C语言是一样的。示例如下: 比如说,我们有引用类型p:i32;,那么可以用 符号执行解引用操作。上例中,v1的类型是i32,p的类型是i32,*p的类型又返回i32。 解引用操作

    2024年01月19日
    浏览(41)
  • 30天拿下Rust之引用

    概述         在Rust语言中,引用机制是其所有权系统的重要组成部分,它为开发者提供了一种既高效又安全的方式来访问和共享数据。引用可以被视为一个指向内存地址的指针,它允许我们间接地访问和操作存储在内存中的数据。与其他语言中的指针不同,Rust中的引用是

    2024年03月10日
    浏览(44)
  • rust学习-引用C库

    #[link(name = \\\"...\\\")] 是一个用于链接外部库的属性宏。 可以在 Rust 代码中引入其他语言编写的动态链接库( .so 、 .dll 等文件),从而实现 Rust 和其他语言的互操作。 #[link(name = \\\"...\\\")] 属性宏用于在 Rust 模块中引入标准 C 库(如 math.h 等)和其他外部库。 name 参数用于指定需要链

    2024年02月10日
    浏览(34)
  • Rust 中的引用与借用

    目录 1、引用与借用  1.1 可变引用 1.2 悬垂引用 1.3 引用的规则 2、slice 类型  2.1 字符串字面量其实就是一个slice 2.2 总结 在之前我们将String 类型的值返回给调用函数,这样会导致这个String会被移动到函数中,这样在原来的作用域不可访问了,但是我们功能一个String值得引用,

    2024年02月05日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包