首页 > 其他分享 >10_rust的结构体struct

10_rust的结构体struct

时间:2023-10-18 11:34:57浏览次数:33  
标签:10 struct name String Rect rust rect u32

rust的struct

定义和实例化struct

使用struct关键字,并对整个struct命名。
在花括号内,对所有字段(Field)定义名称和类型。
创建struct实例:为每个字段指定具体值,无需按声明顺序进行指定。

struct User {
    name: String,
    id: u64,
    is_act: bool,
}
fn main() {
    let u1 = User {
      name: String::from("test"),
      is_act: true,
      id: 12,
    }
}

操作字段

使用点标记法操作字段,一旦struct实例是可变的,那么实例中所有字段都是可变的

struct User {
    name: String,
    id: u64,
    is_act: bool,
}
fn main() {
    let mut u1 = User {
      name: String::from("test"),
      is_act: true,
      id: 12,
    }
    u1.name = String::from("t2");
}

struct作为函数的返回值

struct User {
    name: String,
    id: u64,
    is_act: bool,
}

fn return_struct(nm: String, is_act: bool) -> User {
  User {
    name: nm,
    is_act: is_act,
    id: 0,
  }
}

当字段名与字段值对应变量名相同时,可使用字段初始化简写的方式。

struct User {
    name: String,
    id: u64,
    is_act: bool,
}

fn return_struct(name: String, is_act: bool) -> User {
  User {
    name,
    is_act,
    id: 0,
  }
}

struct的更新语法

当基于某个struct实例创建一个新实例时,可用更新语法:

fn main() {
    let mut u1 = User {
      name: String::from("test"),
      is_act: true,
      id: 12,
    }
    u1.name = String::from("t2");
    let u2 = User {
      name: String::from("test2"),
      ..u1 // 更新语法,表示剩余字段用u1的值来填充
    }
}

tuple struct

tuple struct:定义类似于tuple的struct,tuple struct整体有个命名,但里边元素没有名称。
适应:想给整个tuple起名,使其不同于其他tuple,且无需给每个元素命名。
定义tuple struct:使用struct关键字 名字(元素类型列表)

struct Color(i32, i32, i32);
struct P(i32, i32, i32);
let b = Color(0, 0, 0);
let s = P(0, 0, 0); // s和b是两个不同类型数据

可用模式匹配和点索引的方式访问字段。

Unit-Like struct(没有任何字段)

可定义没有任何字段的struct,叫Unit-Like struct(因为与(),单元类型类似).
适于需要在某个类型上实现某个trait,但没有需要存储的数据。

struct数据的所有权

struct User {
    name: String,
    id: u64,
    is_act: bool,
}

这里字段使用了String而不是&str,该struct实例拥有其所有的数据,只要struct实例有效,其字段也有效。
struct里也可放引用,需使用生命周期的知识。


看个实践:

struct Rect {
    w: u32,
    l: u32,
}

fn main() {
    let rect = (30, 40);
    println!("{}", get_area(rect));
    let rect_struct = Rect {
        w: 30,
        l: 40,
    }
    // 传入不可变的引用,传入后为不可变借用,不会改变变量的所有权,所有权依然归属于main函数
    println!("{}", get_area_struct(&rect_struct));
}

fn get_area(rect: (u32, u32)) -> u32 { // 使用tuple实现
    rect.0 * rect.1 // 无法区分谁是长和宽
}

fn get_area_struct(rect: &Rect) -> u32 { // 使用结构体的不可变的借用即可,无需获得所有权
    rect.w * rect.l
}

rust的打印与调试信息

首先看下直接打印

struct Rect {
    w: u32,
    l: u32,
}

fn main() {
    let rect = Rect {
        w: 30,
        l: 40,
    };
    // 传入不可变的引用,传入后为不可变借用,不会改变变量的所有权,所有权依然归属于main函数
    println!("{}", get_area_struct(&rect));
    println!("{}", rect);
/* 直接打印,编译报错信息(没有实现display):
error[E0277]: `Rect` doesn't implement `std::fmt::Display`
   --> src\main.rs:114:20
    |
114 |     println!("{}", rect);
    |                    ^^^^ `Rect` cannot be formatted with the default formatter
    |
    = help: the trait `std::fmt::Display` is not implemented for `Rect`
    = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
*/
}

fn get_area_struct(rect: &Rect) -> u32 { // 使用结构体的不可变的借用即可,无需获得所有权
    rect.w * rect.l
}

注释中附带的编译报错信息,是指Rect结构体没有实现打印trait std::fmt::Display,不清楚如何打印。其他基础类型能答应是因rust默认实现了这些类型的display trait,而自定义类型无默认实现。
但下一行提示可使用{:?} (or {:#?} for pretty-print)来代替。

struct Rect {
    w: u32,
    l: u32,
}

fn main() {
    let rect = Rect {
        w: 30,
        l: 40,
    };
    // 传入不可变的引用,传入后为不可变借用,不会改变变量的所有权,所有权依然归属于main函数
    println!("{}", get_area_struct(&rect));
    println!("{:?}", rect);
/* 加上{:?}后打印,编译报错信息(变成了没有实现debug):
error[E0277]: `Rect` doesn't implement `Debug`
   --> src\main.rs:114:22
    |
114 |     println!("{:?}", rect);
    |                      ^^^^ `Rect` cannot be formatted using `{:?}`
    |
    = help: the trait `Debug` is not implemented for `Rect`
    = note: add `#[derive(Debug)]` to `Rect` or manually `impl Debug for Rect`
*/
}

fn get_area_struct(rect: &Rect) -> u32 { // 使用结构体的不可变的借用即可,无需获得所有权
    rect.w * rect.l
}

错误信息变成了没有实现debug,debug和display一样,也是一种格式化的方法。下一行提示可加上#[derive(Debug)]或者手动实现debug。这是因为rust默认包含了打印调试信息的功能,但需要显示添加,能直接打印。

#[derive(Debug)] // 需要显示加上打印调试信息
struct Rect {
    w: u32,
    l: u32,
}

fn main() {
    let rect = Rect {
        w: 30,
        l: 40,
    };
    // 传入不可变的引用,传入后为不可变借用,不会改变变量的所有权,所有权依然归属于main函数
    println!("{}", get_area_struct(&rect));
    println!("{:?}", rect); // 一行打印
    println!("\n{:#?}", rect); // 加上#后换行打印
}

fn get_area_struct(rect: &Rect) -> u32 { // 使用结构体的不可变的借用即可,无需获得所有权
    rect.w * rect.l
}
/* 打印输出:
Rect { w: 30, l: 40 }

Rect {
    w: 30,
    l: 40,
}
 */

这是因为rust提供了很多默认的trait(已实现好的函数方法),可用于derive,#[derive(Debug)]中的derive是派生的意思,可利用现有trait,给自定义类型添加很多功能。#[derive(Debug)]整行的意思是让Rect派生于Debug trait,所以才可直接用debug模式打印信息。

标签:10,struct,name,String,Rect,rust,rect,u32
From: https://www.cnblogs.com/UFO-blogs/p/17770644.html

相关文章

  • 10月18日单例模式
    目录单例模式值类的绑定方法,装饰器方式设计模式:实现单例模式的第一种方式第一种方式以类的绑定方法来实现实现单例模式的第二种方式实现单例模式的第三种方式单例模式的核心概念是:只有一个实例对象,而不管有多少人尝试访问它。第四种方法,通过模块导入(python的模块就是单例的体现)......
  • 【2023-10-01】连岳摘抄
    23:59国家是大家的,爱国是每个人的本分。                                                 ——陶行知你很难接受的是:明明我仁至义尽,为什么她这么无情,这么残忍?人世间......
  • 【2023-10-02】连岳摘抄
    23:59兰生幽谷,不为莫服而不芳。舟在江海,不为莫乘而不浮。君子行义,不为莫知而止休。                                                 ——《淮南子》我给你两个学习......
  • 10.18算法
    3的幂给定一个整数,写一个函数来判断它是否是3 的幂次方。如果是,返回true;否则,返回false。整数n是3的幂次方需满足:存在整数x使得n==3x 示例1:输入:n=27输出:true示例2:输入:n=0输出:false示例3:输入:n=9输出:true示例4:输入:n=45输出:false 提示:-231<=n......
  • 分享10个非常好看的QQ空间特效代码
    以下是10种常见的QQ空间特效代码,这些代码可以在QQ空间中实现不同的视觉效果: 1.飘雪特效```javascript:void(newImage().src="http://img.t.sinajs.cn/t35/style/images/common/face/02.gif?v=3.848");```2.彩虹特效```javascript:void(newImage().src="http://img.t.sin......
  • 14.10 Socket 套接字选择通信
    对于网络通信中的服务端来说,显然不可能是一对一的,我们所希望的是服务端启用一份则可以选择性的与特定一个客户端通信,而当不需要与客户端通信时,则只需要将该套接字挂到链表中存储并等待后续操作,套接字服务端通过多线程实现存储套接字和选择通信,可以提高服务端的并发性能,使其能够同......
  • 20231017
    上午学了算法与数据结构中的线索二叉树睡了一整个下午帮助同学在关于开发的问题上躺床上看了编译器相关的书,挺有趣的。编译的几个阶段,语法分析,词法分析,抽象语法树,还有解释器生成器的使用什么的,熟悉但我也不怎么会用的正则表达式,好像编译器也并不是之前认知中的黑盒子了,现在就只......
  • 10.17
    1.UATRLM  执行失败,我login电脑查看,check了log(就是通过error来check的)没仔细看,没想过rerun(只要不涉及DB模块的失败,都可以rerun,没有影响)  好的处理方法:既然已经上线了,能够做的就是就让对方rerun(一般没啥影响,就算各个模块集成来execute,dbscript如果有问题rerun一......
  • Debian衍生桌面项目SpiralLinux12.231001发布
    SpiralLinux 是一个从Debian衍生出来的桌面项目,其重点是在所有主要桌面环境中实现简洁性和开箱即用的可用性。spiralLinux是为刚接触Linux世界的人们量身定制的发行版。这是GeckoLinux开发人员的创意,他更喜欢保持匿名。尽管他不愿透露姓名,但他的操作系统值得称赞,......
  • 10.17每日总结
     今天学习了MapReduce的内容完成了MapReduce的wordcount。  Mapreduce就是在多计算机集群环境中营造一个统一而稳定的存储和计算环境,并能为其他分布式应用服务提供平台支持。也就是说,Hadoop在某种程度上将多台计算机组织成了一台计算机(做同一件事),那么HDFS就相当于这......