文章目录
- 0 引入
- 1、结构体
- 1. 1 结构体
- 1. 2 结构体方法
- 1. 3 元组结构体
- 2、枚举类
- 2.1 match
- 2.2 Option 枚举类
- 3、集合
- 3.1 向量(Vector)
- 3.2 字符串(String)
- 3.1 映射表(Map)
- 4、总结
0 引入
在这里我们需要介绍Rust和数据结构有点关系的语法,如结构体、枚举以及集合。
1、结构体
1. 1 结构体
结构体字C语言中是很重要概念,Rust 中的结构体(Struct)与元组(Tuple)都可以将若干个类型不一定相同的数据捆绑在一起形成整体,但结构体的每个成员和其本身都有一个名字,这样访问它成员的时候就不用记住下标了。元组常用于非定义的多值传递,而结构体用于规范常用的数据结构。结构体的每个成员叫做"字段"。。
//定义一个结构体
struct Animal{
name: String, //后面是,而不是;
size: u32,
belong: String,
home: String
}
//实例化
let dog = Animal{
name: String::from("dog")
size: 15,
belong: String::from("I"),
home: String::from("Anhui")
}
//结构体可以这么用
let name = String::from("dog");
let belong= String::from("I");
let dog= Animal {
name,
size: 15,
belong,
home: String::from("Anhui")
};
//输出结构体
#[derive(Debug)]
fn main() {
let dog2 = Animal{
name: String::from("dog2")
size: 15,
belong: String::from("I"),
home: String::from("Anhui")
}
println!("rect1 is {:?}", dog2 ); //如果属性较多的话可以使用另一个占位符 {:#?} 。
注:
- 不能声明实例,结尾不需要 ; 符号,而且每个字段定义之后用 , 分隔。
- 实例化结构体的时候用 JSON 对象的 key: value 语法来实现定义。
- 一定要导入调试库 #[derive(Debug)] ,之后在 println 和 print 宏中就可以用 {:?} 占位符输出一整个结构体:
也可以使用一个结构体去初始化另一个结构体,但是与C语言不一样的是,就是这两个结构体不能完全一样,至少有一个字段不一样,如下:
let dog= Animal {
name,
size: 15,
belong,
home: String::from("Anhui")
};
let cat = Animal{
name = String::from("cat")
..dog //注意格式
}
1. 2 结构体方法
Rust 语言不是面向对象的,但是面向对象的珍贵思想可以在 Rust 实现。
结构体方法的第一个参数必须是 &self,不需声明类型,因为 self 不是一种风格而是关键字。
在调用结构体方法的时候不需要填写 self ,这是出于对使用方便性的考虑。
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
}
fn main() {
let rect1 = Rectangle { width: 30, height: 50 };
println!("rect1's area is {}", rect1.area());
}
//上述也可以这么实现
impl Rectangle {
fn create(width: u32, height: u32) -> Rectangle {
Rectangle { width, height }
}
}
fn main() {
let rect = Rectangle::create(30, 50); //结构体关联函数,在impl块中省略&self,但是在用的时
// 候需要声明
println!("{:?}", rect);
}
1. 3 元组结构体
有一种更简单的定义和使用结构体的方式:元组结构体。
元组结构体是一种形式是元组的结构体。
与元组的区别是它有名字和固定的类型格式。它存在的意义是为了处理那些需要定义类型(经常使用)又不想太复杂的简单数据:
struct Color(u8, u8, u8);
struct Point(f64, f64);
let black = Color(0, 0, 0);
let origin = Point(0.0, 0.0);
元组结构体每个对象可以像结构体那样用下标去访问
println!("black = ({}, {}, {})", black.0, black.1, black.2);
2、枚举类
2.1 match
枚举类在 Rust 中并不像其他编程语言中的概念那样简单,有着自己不一样的概念和用法,枚举的目的是对某一类事物的分类,分类的目的是为了对不同的情况进行描述。基于这个原理,往往枚举类最终都会被分支结构处理(许多语言中的 switch )
定义一个简单的枚举
enum Book {
Papery(u32), //纸质书
Electronic(String) //电子书
}
fn main() {
enum Book {
Papery {index: u32},
Electronic {url: String},
}
let book = Book::Papery{index: 1001};
let ebook = Book::Electronic{url: String::from("url...")};
match book {
Book::Papery { index } => {
println!("Papery book {}", index);
},
Book::Electronic { url } => {
println!("E-book {}", url);
}
}
}
2.2 Option 枚举类
Option 是 Rust 标准库中的枚举类,这个类用于填补 Rust 不支持 null 引用的空白。
enum Option<T> {
Some(T),
None,
}
使用方法
fn main() {
let opt = Option::Some("Hello");
match opt {
Option::Some(something) => {
println!("{}", something);
},
Option::None => {
println!("opt is nothing");
}
}
}
//省略Option 简介写法
fn main() {
let t = Some(64);
match t {
Some(64) => println!("Yes"),
_ => println!("No"),
}
}
// 也可以用 if let 语法再一次简洁,有点语法糖的感觉
fn main() {
enum Book {
Papery(u32),
Electronic(String)
}
let book = Book::Electronic(String::from("url"));
if let Book::Papery(index) = book {
println!("Papery {}", index);
} else {
println!("Not papery book");
}
}
3、集合
集合(Collection)是数据结构中最普遍的数据存放形式,Rust 标准库中提供了丰富的集合类型帮助开发者处理数据结构的操作。
3.1 向量(Vector)
向量(Vector)是一个存放多值的单数据结构,该结构将相同类型的值线性的存放在内存中。
向量是线性表,在 Rust 中的表示是 Vec。
向量的使用方式类似于列表(List),我们可以通过这种方式创建指定类型的向量:
let vector: Vec<i32> = Vec::new(); // 创建类型为 i32 的空向量
let vector = vec![1, 2, 4, 8]; // 通过数组创建向量
vector.push(16); //追加
let mut v1: Vec<i32> = vec![1, 2, 4, 8];
let mut v2: Vec<i32> = vec![16, 32, 64];
v1.append(&mut v2); //拼接
取出数据使用 get,当然也可以像数组那样,使用下标(注意越界)
fn main() {
let mut v = vec![1, 2, 4, 8];
println!("{}", match v.get(0) {
Some(value) => value.to_string(),
None => "None".to_string()
});
}
3.2 字符串(String)
字符串的使用和C差不多,很方便可以作为各种数据的转换,拼接,切片等
let string = String::new();
let one = 1.to_string(); // 整数到字符串
let hello = String::from("Hello");
let mut s = String::from("run");
s.push_str("oob"); // 追加字符串切片
s.push('!'); // 追加字符
3.1 映射表(Map)
映射表(Map)在其他语言中广泛存在。其中应用最普遍的就是键值散列映射表(Hash Map)。
use std::collections::HashMap;
fn main() {
let mut map = HashMap::new();
map.insert("color", "red");
map.insert("size", "10 m^2");
println!("{}", map.get("color").unwrap());
//遍历打印
for p in map.iter() {
println!("{:?}", p);
}
}
map中如果在insert有相同的数据,则会覆盖掉原先数据,如果想安全插入
map.entry("color").or_insert("red");
4、总结
关于数据结构这块,Rust能够使用部分的数据结构,在枚举这一块稍微不一样。
–