您的位置:首页 > 房产 > 建筑 > rust 初探 -- struct

rust 初探 -- struct

2024/10/5 18:27:04 来源:https://blog.csdn.net/shenyongsi/article/details/140656273  浏览:    关键词:rust 初探 -- struct

rust 初探 – struct

定义和实例化 struct

定义 struct

示例:

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

实例化 struct

  • 实例化的顺序可以不一样
  • 但是必须给所有字段都赋值
一些操作方法
  • 使用点标记法获取某个值:user1.email
  • 一旦 struct 的实例是可变的,那么里面所有的字段都是可变的
  • 字段初始化简写:当字段名和字段值对应变量名相同时,可以使用字段初始化简写
fn build_user(email: String, username: string) -> User {User {email,username,active: true,sign_in_count: 1,}
}
  • 当基于某个 struct 实例来创建一个新实例的时候,使用更新语法:
let user2 = User {email: String::from("user2_email"),username: String::from("user2_name"),active: use1.active,sign_in_count: use1.sign_in_count,};
let user2 = User {email: String::from("user2_email"),username: String::from("user2_name"),..user1};
  • tuple struct: struct Color(i32, i32),不同名的是不同的数据类型
  • Unit-Like Struct:没有任何字段的 struct,适用于需要在某个类型上实现某个 trait,但是在里面又没有想要存储的数据
struct 数据所有权
  • 如果 struct 里面没有存放引用,那么 struct 实例拥有其所有的数据,只要 struct 是有效的,那么里面的字段数据也是有效的
  • 如果存放了引用,那么就需要使用生命周期,生命周期保证只要 struct 实例是有效的,那么里面的引用也是有效的(否则报错)

struct 例子

// 这样子就可以未自定义的 struct 进行打印,因为自定义的没有实现 Display, Debug 的trait
#[derive(Debug)]
struct Rectangle {width: u32,length: u32,
}fn main() {let rec = Rectangle {width: 20,length: 10,};println!("{}", area(&rec));println!("{:#?}", rec);
}fn area(rec: &Rectangle) -> u32 {rec.length * rec.width
}

struct 方法

相关定义

  • 方法和函数类似:fn 关键字、名称、参数、返回值
  • 方法和函数不同之处:
    • 方法是在 struct 的上下文中定义
    • 第一个参数是 self,表示方法被调用的 struct 实例
  • 每个 struct 可以有多个 impl
#[derive(Debug)]
struct Rectangle {width: u32,length: u32,
}// impl 声明块,在块里面定义方法
impl Rectangle {// 上下文// self 会自动推断为 Rectangle// 可以是 &self,也可以获得其所有权或可变借用// 这样会有更好的代码组织fn area(&self) -> u32 {self.length * self.width}
}fn main() {let rec = Rectangle {width: 20,length: 10,};println!("{}", rec.area());println!("{:#?}", rec);
}

方法调用的运算符

  • Rust 会自动引用或者解引用:在调用方法的时候,会根据情况自动添加 &、&mut 或者 *,以便 object 可以匹配方法的签名
  • p1.distance(&p2); 等效 (&p1).distance(&p2);

方法参数

  • 除了 self,还可以添加其他参数,如 can_hold 函数:
#[derive(Debug)]
struct Rectangle {width: u32,length: u32,
}// impl 声明块,在块里面定义方法
impl Rectangle {// 上下文// self 会自动推断为 Rectangle// 可以是 &self,也可以获得其所有权或可变借用// 这样会有更好的代码组织fn area(&self) -> u32 {self.length * self.width}fn can_hold(&self, other: &Rectangle) -> bool {self.width > other.width && self.length > other.length}
}fn main() {let rec = Rectangle {width: 20,length: 10,};println!("{}", rec.area());println!("{:#?}", rec);let rec1 = Rectangle {width: 10,length: 5,};let rec2 = Rectangle {width: 30,length: 50,};println!("rec1 can hold: {}", rec.can_hold(&rec1));println!("rec2 can hold: {}", rec.can_hold(&rec2));
}

关联函数

  • 可以在 impl 块里定义不把 self 作为第一个参数的函数,它们叫做关联函数(不是方法)
  • 关联函数通常用于构造器
	#[derive(Debug)]
struct Rectangle {width: u32,length: u32,
}// impl 声明块,在块里面定义方法
impl Rectangle {// 上下文// self 会自动推断为 Rectangle// 可以是 &self,也可以获得其所有权或可变借用// 这样会有更好的代码组织fn area(&self) -> u32 {self.length * self.width}fn can_hold(&self, other: &Rectangle) -> bool {self.width > other.width && self.length > other.length}fn square(size: u32) -> Rectangle {Rectangle {width: size,length: size,}}
}fn main() {let s = Rectangle::square(3);// :: 符号:用于关联函数,或者模块创建的命名空间println!("{}", s.area());println!("{:#?}", s);let rec1 = Rectangle {width: 10,length: 5,};println!("s can hold: {}", rec1.can_hold(&s));
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com