Rust struct 结构体

发布时间: 更新时间: 总字数:1393 阅读时间:3m 作者: IP上海 分享 网址

结构体(struct)是将一组自定义的数据类型命名,并打包为一个整体。

介绍

  • 定义 struct 示例:
struct 结构体名称 {
  属性1: 类型,  // 字段
  属性2: 类型,
}
  • 实例化 struct:创建 struct 示例才能使用 struct

    • 为每个字段指定具体值
    • 字段是无序的
    • 实例化时必须为所有字段赋值
    • 通过点(dot)标记法获取具体字段的值和赋值
    • 使用 let 默认示例化的 struct 是不可变(immutable),可以通过 let mut 声明可变(mutable)的 struct
    • 可变的 struct 实例,所有字段都是可变的
    • struct 可以作为函数的返回值,如 -> City
    • 简写规则:若字段名和字段值对应变量名相同时,可以使用字段名初始化
  • struct 更新:基于某个 struct 实例创建一个新的 struct 实例时,可以在新的实例中使用 ..实例名 来替代不需要修改的字段,需要修改的字段需要单独指定

  • struct 数据所有权

    • 若实例拥有 struct 里所有字段的所有权,则 struct 拥有所有权
    • 若存在引用(如 &str)类型的字段,则需要使用 生命周期(lifetime specifier)
      • 若生命周期保证struct实例是有效的,则里面的引用也是有效的
      • 若struct里面存储引用,且不使用生命周期,则会报错
  • 示例

struct City {
	name:    String,
	no:      String,
	age:     u32,
}

fn main() {
    let mut city = City {
        no: String::from("021"),
        name: String::from("shanghai"),
        age: 10,
    };

    println!("name: {}, no: {}, age: {}", city.name, city.no, city.age);

    city.age += 1;
    println!("name: {}, no: {}, age: {}", city.name, city.no, city.age);

    let city = new_city(String::from("shanghai"), String::from("021"), 10);
    println!("name: {}, no: {}, age: {}", city.name, city.no, city.age);

    // struct 更新
    let city2 = City {
        name: String::from("moudu"),
        ..city
    };
    println!("name: {}, no: {}, age: {}", city2.name, city2.no, city2.age);
}

// 初始化简写示例
fn new_city(name: String, no: String, age: u32) -> City {
    City {
        no,  // 简写:初始化字段 no 为变量 no 的值,下同
        name,
        age: age, // 非简写
    }
}

tuple struct

  • 定义:使用 struct 关键字,后面跟名字,并在小括号中指定类型,如下:
struct 结构体名称(类型1, 类型2, 类型3);
  • 示例
struct Color(u32, u32, u32);

fn main() {
    let black = Color(0, 0, 0);
    println!("{}", black.0)
}

Unit-Like Struct

  • 定义:Unit-Like Struct 是在 Rust 中定义的没有任何字段的 struct
  • 使用场景:适用于需要在某个类型上实现某个 trait,但里面不需要存储数据

struct 方法

struct 方法和函数类似,由 fn 声明、函数名称、参数、返回值组成

  • impl 块里定义方法,一个 struct 可以有多个 impl
  • struct 方法的第一个参数是 &self,也可以获得其所有权和可变借用
  • 结构体实例使用 . 方法调用方法
struct 结构体名称 {
  属性1: 类型,  // 字段
  属性2: 类型,
}

impl 结构体名称 {
    fn 函数名(&self) -> 返回值 {  //self 为结构体示例
    // fn 函数名(&mut self) -> 返回值 {
        // 实现
        self.属性1
    }
}

struct 方法 vs 函数:

  • struct 方法struct(或 enum、trait 对象)的上下文中定义
  • struct 方法 的第一个参数是 self,表示方法被调用的 struct 示例

示例:

struct City {
	name:    String,
	no:      String,
	age:     u32,
}

impl City {
    fn display(&self) {
        println!("name: {}, no: {}, age: {}", self.name, self.no, self.age)
    }
}

fn main() {
    let city = City {
        no: String::from("021"),
        name: String::from("shanghai"),
        age: 10,
    };

    city.display();
}

方法调用的运算符

传统的 C/C++ 中,point_obj->somefun()(*point_obj).somefun() 功能一样,但Rust没有 -> 运算符

Rust(和Golang一样)使用 . 调用方式时自动的引用和解引用,即 Rust 会根据情况自动添加 &&mut*,以便实例可以匹配对方

  • 下面的方法是相同的
    • p1.distance(&p2)
    • (&p1).distance(&p2)
  • 与 Golang 略有区别(golang 结构体方法

关联函数

关联函数:在 impl 块里定义的函数,第一个参数不是 self

  • 作用:通常用于构造器
  • 调用:结构体名称::函数名()
    • :: 符号的作用
      • 关联函数
      • 模块创建的命名空间
  • 示例:String::from()
#[derive(Debug)]
struct City {
	name:    String,
	no:      String,
	age:     u32,
}

impl City {
    fn new(name: &str, no: &str, age: u32) -> City {
        City {
            name: String::from(name),
            no: String::from(no),
            age
        }
    }
}

fn main() {
    let city = City::new("shanghai", "021", 10);

    println!("{:?}", city)
}

pub struct

定义共有 Struct,pub struct 定义公有的 struct:

  • struct 的字段默认是私有的
  • struct 的字段前需要单独设置 pub 来变为公有的
pub struct City {
    pub name: String,
    pub no: String,
    ...
}
Home Archives Categories Tags Statistics
本文总阅读量 次 本站总访问量 次 本站总访客数