结构体

对于rust的结构体定义和使用只对于几个特别需要注意的点进行说明,基本用法就不多叙述。

  1. 变量与字段名同名时简写语法
    可以直接对应各字段变量名称,不用采用 字段名:变量名的方式

    struct Book {
     name:String,
     price:f32,
     pages:u32,
     author:String,
     publishingHouse:String,
    }
    
    fn initBook(name:String, price:f32, pages:u32, author:String, publishingHouse:String) -> Book {
     Book { 
         name,
         price, 
         pages, 
         author,
         publishingHouse,
     }
    }
  2. 引用类型结构体字段
    存储引用数据需要加上生命周期,否则会在编译时报错(生命周期下一节说明)

    struct DataRef{
     elementRef1:&str, //Error:missing lifetime specifier
     elementRef2:&i32, //Error:missing lifetime specifier
    }

    更改为

    struct DataRef<'a> {
     elementRef1:&'a str,
     elementRef2:&'a i32,
    }

    就可以编译通过。 其中'a是定义生命周期

  3. 结构体间赋值
    一个已经存在的结构体的中的部分信息可以赋值给新的结构体

     #[derive(Debug)]
     struct Book {
         name:String,
         price:f32,
         pages:u32,
         author:String,
         publishingHouse:String,
     }
    
     let book1 = initBook(
         String::from("Cray rust"), 
         88.0, 
         600, 
         String::from("Jack"), 
         String::from("xxx"));
         
     let book2 = Book{
         name:String::from("Master rust"),
         price:96.0,
         pages: 800,
         ..book1
     };
    
     println!("{:?}", book2);
     //println!("{:?}", book1); //Error:borrow of partially moved value: `book1`

    book1中的作者和出版社信息与book2一样,我们可以在book2赋值时,通过..book1将book1中的值进行复制。

    我们还要注意一下,

    • 如果..book1后我们再使用book1就会在编译时报错:borrow of partially moved value: book1这是因为book1中的author和publishingHouse已经发生了所有权转移
    • 在结构体定义上方有这一句#[derive(Debug)]。这是导入调试库 #[derive(Debug)]
    • 在 println!就可以用 {:?} 占位符输出一整个结构体,也可以使用{:#?}优化输出结构体显示
  1. 元组结构体
    之前已经介绍过元组,元组结构体就是用元组的方式定义结构体。元组结构体存在的意义就是为了方便。看个例子就明白了,定义坐标位置,颜色等可以简单方便的使用元组结构体

     struct RGB(u32,u32,u32);
     struct Position(f32, f32,f32);
    
     let Red = RGB(255,0,0);
     let StartPosition = Position(10.0, 10.0, 0.0);
    
     println!("Red({},{},{})", Red.0, Red.1, Red.2);
     println!("StartPositon({},{},{})", StartPosition.0, StartPosition.1, StartPosition.2);
  2. 方法
    方法与之前介绍的函数类似,只是方法是针对结构体的。
    结构体方法的第一个参数是self,不需要声明,self是关键字。
    self的使用类似于C++中的this,但不能于C++的this相提并论。
    struct Rectangle {
        width: u32,
        height: u32,
    }

    impl Rectangle {
        fn area(&self) -> u32 {
            self.width * self.height
        }

        fn compare(&self, rec:&Rectangle) -> bool {
            if self.area() > rec.area() {
                true
            } else {
                false
            }
        }
    }

    let rec1 = Rectangle{width:10, height:10};
    let rec2 = Rectangle{width:12, height:9};

    println!("Is rec1 larger than rec2:{}", rec1.compare(&rec2));

6.关联函数
函数之前说过,关联函数就是于结构体关联的函数。之前用过String::from("xxx")这个函数,这就是String的关联函数。
关联函数不依赖于实例,可以理解为C++的构造函数。
关联函数一样在impl区域内实现,只是不需要self

    struct Rectangle {
        width: u32,
        height: u32,
    }

    impl Rectangle {
        fn constructor(width:u32, height:u32) -> Rectangle{
            Rectangle{width,height}
        }

        fn area(&self) -> u32 {
            self.width * self.height
        }

        fn compare(&self, rec:&Rectangle) -> bool {
            if self.area() > rec.area() {
                true
            } else {
                false
            }
        }
    }

    let rec1 = Rectangle::constructor(10, 10);
    let rec2 = Rectangle::constructor(12, 9);

麦穗儿
127 声望15 粉丝

程序猿以技术为本


« 上一篇
Rust教程<二>
下一篇 »
Rust教程<四>