• rust的struct


    定义struct

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

    实例化struct

    • 想要使用struct,需要创建strut的实例
    1. 为每个字段知道具体值
    2. 无需按声明的顺序进行指定
    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
    1. tuple struct 整体有个名,但里面的元素没有名
    2. 适用:想给整个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
    1. 改struct实例拥有其所有的数据
    2. 只有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关键字、名称、参数、返回值
    • 方法与函数不同之处
    1. 方法是在struct(或enum、trait对象)的上下文中定义
    2. 第一个参数是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会自动引用或解引用
    1. 在调用方法时就会发生这种行为
    • 在调用方法时,rust根据情况自动添加&、&mut或*,以便object可以匹配方法的签名。
    • 下面两行代码效果相同
    p1.distance(&p2);
    (&p1).distance(&p2);
    

    关联函数

    • 可以在impl块里定义不把self作为第一个参数的函数,它们叫做关联函数(不是方法)
    String::from();
    
    • 关联函数通常用于构造器
    • ::符号
    1. 关联函数
    2. 模块创建的命名空间
    #[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块
  • 相关阅读:
    LeetCode-45-跳跃游戏Ⅱ-贪心算法
    云数一体机
    失踪人口回归
    几个常用的函数
    干货 | Burpsuite的使用tips总结
    Java如何解析html里面的内容并存到数据库
    【开源】基于Vue和SpringBoot的服装店库存管理系统
    为什么在使用onnxruntime-gpu下却没有成功调用GPU?
    动态代理(cglib与jdk)
    视频生成的发展史及其原理解析:从Gen2、Emu Video到PixelDance、SVD、Pika 1.0
  • 原文地址:https://blog.csdn.net/fan_music/article/details/127104363