解析rust中的struct

 更新时间:2022年10月08日 11:55:32   作者:fan_music  
自定义的数据类型,为相关联的值命名,打包成有意义的组合,类似python的dict,但是赋值的时候可以不按顺序,本文给大家介绍下rust中的struct知识,感兴趣的朋友一起看看吧

定义struct

  • 使用struct关键字,并为整个struct命名
  • 在花括号内,为所有字段(field)定义名称和类型
struct User{
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

实例化struct

  • 想要使用struct,需要创建strut的实例
  • 为每个字段知道具体值
  • 无需按声明的顺序进行指定
struct User{
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

fn main(){
    let user1 = User{
        username: String::from("xxxx"),
        email: String::from("xxxx@163.com"),
        active: true,
        sign_in_count:556,
    };
    println!("username:{}", user1.username);
    println!("email:{}", user1.email);
    println!("active:{}", user1.active);
    println!("sign_in_count:{}", user1.sign_in_count);
}

取得struct里面的某个值

使用点标记法

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

fn main(){
    let mut user1 = User{
        username: String::from("xxxx"),
        email: String::from("xxxx@163.com"),
        active: true,
        sign_in_count:556,
    };
    // 注意 user1 必须是可变的 
    user1.username = String::from("hhhhhhh");
    println!("username:{}", user1.username);
    println!("email:{}", user1.email);
    println!("active:{}", user1.active);
    println!("sign_in_count:{}", user1.sign_in_count);
}

注意

一旦struct的实例是可变的,那么实例中的所有字段都是可以变的

struct作为函数的放回值

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

fn build_user(email: String, username: String)-> User{
    User{
        email: email,
        username: username,
        active: true,
        sign_in_count:1,
    }
}

fn main(){
    let email = String::from("xxxx@163.com");
    let username = String::from("llllll");
    let user1 = build_user(email, username);
    println!("username:{}", user1.username);
    println!("email:{}", user1.email);
    println!("active:{}", user1.active);
    println!("sign_in_count:{}", user1.sign_in_count);
}

字段初始化简写

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

fn build_user(email: String, username: String)-> User{
    User{
        email,
        username,
        active: true,
        sign_in_count:1,
    }
}

struct更新语法

当你想基于某个struct实例来创建一个新实例的时候,可以使用struct更新语法

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

fn build_user(email: String, username: String)-> User{
    User{
        email,
        username,
        active: true,
        sign_in_count:1,
    }
}

fn main(){
    let email = String::from("xxxx@163.com");
    let username = String::from("llllll");
    let user1 = build_user(email, username);
    // user2 email 重新赋值
    // user2 其他变量 使用 user1 的值
    // String 类型会被引用 从而失效
    let user2 = User{
        email: String::from("user2@163.com"),
        ..user1
    };
    // user1.username 被 user2.username 引用 从而失效
    // println!("username:{}", user1.username);
    println!("username:{}", user2.username);
    println!("email:{}", user1.email);
    println!("email:{}", user2.email);
    println!("active:{}", user1.active);
    println!("sign_in_count:{}", user1.sign_in_count);
}

tuple struct

  • 可定义类似tuple的struct,叫做tuple struct
  • tuple struct 整体有个名,但里面的元素没有名
  • 适用:想给整个tuple起名,并且它不同于其它tuple,而且又不需要给每个元素
  • 定义tuple struct:使用struct关键字,后边是名字,以及里面元素的类型
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
let black = Color(0, 2, 3);
let origin = Point(3, 2, 3);

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

  • 可以定义没有任何的struct,叫做Unit-Like struct(因为与{},单元类型类似)
  • 使用与需要在某个类型上失效某个trait,但是在里面有没有想要存储的数据结构

struct数据的所有权

struct User{
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}
  • 这里的字段使用了String而不是&str
  • 改struct实例拥有其所有的数据
  • 只有struct实例是有效的,那么里面的字段也是有效的
  • struct里面也是存放引用,但是需要使用生命周期

什么事struct

  • std::fmt::Display
  • std::fmt::Debug
  • #[derive(Debug)]
  • {:?}
  • {:#?}
#[derive(Debug)]
struct Rectangle{
    width: u32,
    length: u32,
}
fn main(){
    let rect = Rectangle{
        width: 22,
        length: 44,
    };
    println!("{}", area(&rect));
    println!("{:?}", rect);
    println!("{:#?}", rect);
}
fn area(rect: &Rectangle)-> u32{
    rect.length * rect.width
}

struct的方法

  • 方法和函数类似:fn关键字、名称、参数、返回值
  • 方法与函数不同之处
  • 方法是在struct(或enum、trait对象)的上下文中定义
  • 第一个参数是self,表示方法被调用的struct实例

定义方法

#[derive(Debug)]
struct Rectangle{
    width: u32,
    length: u32,
}
impl Rectangle{
    fn area(&self)-> u32{
        self.width * self.length
    }
}
fn main(){
    let rect = Rectangle{
        width: 33,
        length: 44,
    };
    println!("{}", rect.area());
    println!("{:#?}", rect);
}
  • 在impl块里定义方法
  • 方法的第一个参数可以是&self,也可以获得其所有权或可变借用。其他参数一样。
  • 更良好的代码组织。

​​​​​​​​​​​​​​方法调用的运算符

  • C/C++:object->somthing()和(*object).something()一样
  • rust没有->运算符
  • rust会自动引用或解引用
  • 在调用方法时就会发生这种行为
  • 在调用方法时,rust根据情况自动添加&、&mut或*,以便object可以匹配方法的签名。
  • 下面两行代码效果相同
p1.distance(&p2);
(&p1).distance(&p2);

关联函数

  • 可以在impl块里定义不把self作为第一个参数的函数,它们叫做关联函数(不是方法)
String::from();
  • 关联函数通常用于构造器
  • ::符号
  • 关联函数
  • 模块创建的命名空间
#[derive(Debug)]
struct Rectangle{
    width: u32,
    length: u32,
}
impl Rectangle{
    fn square(width: u32, length: u32)->Rectangle{
        Rectangle{
            width,
            length,
        }
    }
}
fn main(){
    let rect = Rectangle::square(33, 11);
    println!("width:{}", rect.width);
    println!("length:{}", rect.length);
    println!("{:#?}", rect);
}

多个impl块

  • 每个struct运行拥有多个impl块

到此这篇关于解析rust中的struct的文章就介绍到这了,更多相关rust struct内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • rust类型转换的实现

    rust类型转换的实现

    Rust是类型安全的语言,因此在Rust中做类型转换不是一件简单的事,本文主要介绍了rust类型转换的实现,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • RUST语言函数的定义与调用方法

    RUST语言函数的定义与调用方法

    定义一个RUST函数使用fn关键字,下面通过本文给大家介绍RUST语言函数的定义与调用方法,感兴趣的朋友跟随小编一起看看吧
    2024-04-04
  • Rust中的Copy和Clone对比分析

    Rust中的Copy和Clone对比分析

    这篇文章主要介绍了Rust中的Copy和Clone及区别对比分析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-04-04
  • 使用Rust语言编写一个ChatGPT桌面应用示例详解

    使用Rust语言编写一个ChatGPT桌面应用示例详解

    这篇文章主要介绍了如何用Rust编写一个ChatGPT桌面应用,文中有详细的流程介绍,对大家的学习或工作有意一定的帮助,需要的朋友可以参考下
    2023-05-05
  • Rust生命周期之验证引用有效性与防止悬垂引用方式

    Rust生命周期之验证引用有效性与防止悬垂引用方式

    本文介绍了Rust中生命周期注解的应用,包括防止悬垂引用、在函数中使用泛型生命周期、生命周期省略规则、在结构体中使用生命周期、静态生命周期以及如何将生命周期与泛型和特质约束结合,通过这些机制,Rust在编译时就能捕获内存安全问题
    2025-02-02
  • Rust Atomics and Locks内存序Memory Ordering详解

    Rust Atomics and Locks内存序Memory Ordering详解

    这篇文章主要为大家介绍了Rust Atomics and Locks内存序Memory Ordering详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • Rust中HashMap类型的使用详解

    Rust中HashMap类型的使用详解

    Rust中一种常见的集合类型是哈希映射,本文主要介绍了Rust中HashMap类型的使用详解,包含创建访问修改遍历等,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • 详解Rust中三种循环(loop,while,for)的使用

    详解Rust中三种循环(loop,while,for)的使用

    我们常常需要重复执行同一段代码,针对这种场景,Rust 提供了多种循环(loop)工具。一个循环会执行循环体中的代码直到结尾,并紧接着回到开头继续执行。而 Rust 提供了 3 种循环:loop、while 和 for,下面逐一讲解
    2022-09-09
  • Rust动态调用字符串定义的Rhai函数方式

    Rust动态调用字符串定义的Rhai函数方式

    Rust中使用Rhai动态调用字符串定义的函数,通过eval_expression_with_scope实现,但参数传递和函数名处理有局限性,使用FnCall功能更健壮,但更复杂,总结提供了更通用的方法,但需要处理更多错误情况
    2025-02-02
  • Rust调用Windows API 如何获取正在运行的全部进程信息

    Rust调用Windows API 如何获取正在运行的全部进程信息

    本文介绍了如何使用Rust调用WindowsAPI获取正在运行的全部进程信息,通过引入winapi依赖并添加相应的features,可以实现对不同API集的调用,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-11-11

最新评论