首页 > 其他分享 >Rust随笔——结构体打印和所有权转移

Rust随笔——结构体打印和所有权转移

时间:2023-07-29 23:47:52浏览次数:37  
标签:所有权 name 打印 Rust rectangle 随笔 rectangle2 Rect String

结构体打印

如果想打印结构体,并不能使用如以下方式进行打印

println!("{}",rectangle);


会出现上图所示的错误,通过阅读不难得出——报错原因为Rect类型没有实现std::fmt::Display这个trait。
第一个note建议我们使用{:?}或{:#?}来代替{}进行输出,于是尝试修改后进行构建

修改后,发现仍然报错,但报错内容发生改变。此时提示Rect不能被{:?}进行格式化。
当我们使用println!宏进行输出时,如果使用{},那么即宣告使用std::fmt::Display。根据help的内容,提示Rect没有实现Debug这个trait.所以要尝试解决这个问题。
第一个note提示可以加入#[derive(Debug)]给Rect或者手动为Rect实现Debug来解决,那么毫无疑问肯定采用前者处理。
此时代码就变成了下图所示


成功运行。

所有权转移

#[derive(Debug)]
struct Rect {
    name: String,
    width: u32,
    length: u32,
}

fn main() {
    let rectangle = Rect {
        name: String::from("123"),
        width: 50,
        length: 20,
    };
    let rectangle2 = Rect {
        width: 50,
        ..rectangle
    };
    println!("{}", rectangle.name)
}

上述代码无法正常运行,报错信息如下:

其中报错的部分rectangle.name提示为——当所有权转移后值被借用,而值的所有权移动发生在rectangle2中。
在Rust中,除了基本类型外,其他类型的数据会被存放在堆上,在赋值时并不会在堆上拷贝一份。因为这对性能存在较大影响。
为了保证程序的安全,Rust在尝试拷贝被分配的内存时,会使第一个变量的所有权转移给第二个变量,使得第一个变量无效。在上述代码中的表现为,rectangle2中的name字段获得了rectangle的所有权,此时rectangle中的非基本类型就无法再使用了。当rectangle2离开自己的作用域时,也会自动释放自己的内存。
根据第一条note的信息,发生所有权转移的原因是String类型并没有实现Copy这个trait。
那么解决问题的方式就很清晰了,要么为String实现copy,要么使用获得所有权的rectangle2即可。

#[derive(Debug)]
struct Rect {
    name: String,
    width: u32,
    length: u32,
}

fn main() {
    let rectangle = Rect {
        name: String::from("123"),
        width: 50,
        length: 20,
    };
    let rectangle2 = Rect {
        name: rectangle.name.clone(),
        ..rectangle
    };
    println!("{}", rectangle.name);
    println!("{}", rectangle2.width);
    println!("{}", rectangle2.length);
}

既然问题出在String这个非基本类型的所有权转移,那么可不可以想办法使得其在堆上拷贝一份。答案是可行的。为堆上的数据使用clone函数,就可以实现这一点。
而另外一个解决方案就是使用rectangle2输出即可,此方法较为简单,不再赘述。

标签:所有权,name,打印,Rust,rectangle,随笔,rectangle2,Rect,String
From: https://www.cnblogs.com/appletree24/p/17590796.html

相关文章

  • 开源了一套wms系统,支持lodop和网页打印入库单、出库单。
    若依wms简介若依wms是一套基于若依的wms仓库管理系统,支持lodop和网页打印入库单、出库单。毫无保留给个人及企业免费使用。前端采用Vue、ElementUI(antdesign正在开发中)。后端采用SpringBoot、SpringSecurity、Redis&Jwt。权限认证使用Jwt,支持多终端认证系统。支持加载动态权......
  • golang打印指针切片/数组的值
     FmtSlice2String方法可以将指针切片的值打印处理packagemainimport( "fmt" "reflect")typeStudentstruct{ Namestring`json:"name"cn:"名字"` Ageuint64`json:"age"cn:"年龄"`}funcmain(){ s:=mak......
  • Robot Framework自动化测试随笔(二)
    二、Web自动化(1)1.安装selenium2library库pipinstallrobotframework-selenium2library 2.指定报告的生成路径在【Run】标签下,配置Arguments路径:-dD:\python37\log 3.网页元素自动化,对所有元素操作分两步:⑴定位元素(谷歌、火狐建议使用xpath,IE建议使用css)⑵对元素......
  • 三个线程循环打印ABC10次的几种解决方法
    有三个线程分别打印A、B、C,请用多线程编程实现,在屏幕上循环打印10次ABCABC… 这是一个比较常用的关于线程的考题,一般出现在应届生的校园招聘试卷上。本文给出如下四种解决方法:使用synchronized,wait和notifyAll使用Lock和Condition使用Semaphore使用AtomicInteger使用synchro......
  • NET6 EF Error: The certificate chain was issued by an authority that is not trus
    ErrorAconnectionwassuccessfullyestablishedwiththeserver,butthenanerroroccurredduringtheloginprocess.(provider:SSLProvider,error:0-Thecertificatechainwasissuedbyanauthoritythatisnottrusted.)解决方法:在DB连接字符串后面添加......
  • Java 打印在控制台 方法
    Java打印在控制台的方法在Java编程语言中,控制台是一种常用的输出方式。它允许程序员在调试和开发过程中查看程序的输出结果。本文将介绍几种在Java中打印输出的方法,并提供相应的代码示例。1.使用System.out.println()System.out.println()是Java中最常用的打印输出方法之一。......
  • .net core 调用打印机打印pdf文件 FreeSpire.PDF
    首先,参考了https://stackoverflow.com/questions/63941980/is-it-possible-to-print-documents-from-a-net-core-3-1-windows-service中的说明,声明:我用的是core3.1测试的先下载了FreeSpire.PDF的NuGet包,可以看出来简介上是支持print的: 然后我的测试直接在controller中:1[......
  • java 打印调用栈
    Java打印调用栈介绍在Java开发中,了解如何打印调用栈是非常重要的。调用栈(CallStack)是用于追踪程序执行期间方法的调用顺序的一种机制。通过打印调用栈,我们可以获得有关程序执行路径和调用层次的有用信息,这对于调试和问题排查非常有帮助。在本文中,我将指导你如何实现Java打印调......
  • java 打印标签源码
    Java打印标签源码实现教程作为一名经验丰富的开发者,我将教会你如何实现Java打印标签源码的功能。下面是整个实现过程的步骤:步骤实现内容步骤一连接打印机步骤二创建打印标签的模板步骤三填充标签模板数据步骤四打印标签接下来,我将详细介绍每个步骤需要......
  • 用 Rust 生成 Ant-Design Table Columns
    经常开发表格,是不是已经被手写Ant-DesignTable的Columns整烦了?尤其是ToB项目,表格经常动不动就几十列。每次照着后端给的接口文档一个个配置,太头疼了,主要是有时还会粘错就尴尬了。那有没有办法能自动生成columns配置呢?当然可以。目前后端的接口文档一般是使用Swagger来生成的,S......