解析rust中的struct

2022-10-09 17:07:58
目录
定义struct实例化struct取得struct里面的某个值struct作为函数的放回值字段初始化简写struct更新语法tuple structUnit-Like Struct(没有任何字段)struct数据的所有权什么事structstruct的方法定义方法​​​​​​​​​​​​​​方法调用的运算符关联函数多个impl块

定义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>
          可定义类似tuple的struct,叫做tuple structtuple 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,叫做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::Displaystd::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>