数据类型
标量类型
复合类型
struct
定义struct
示例如下:
1 2 3 4 5
| struct User { name: String, age: u32 email: String, }
|
实例化struct
创建struct的实例,需要满足以下条件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| struct User { name: String, age: u32, sex: String, email: String, }
fn main() { let user1 = User { name: String::from("Zhang San"), age: 28, sex: String::from("male"), email: String::from("zhangsan123@163.com"), };
println!("{} {} {} {}", user1.name, user1.age, user1.sex, user1.email); }
|
注意:当字段名与字段值对应的变量名相同时,可以使用字段初始化简写的方式,示例如下
1 2 3 4 5 6 7 8
| fn build_user(name: String, email: String) -> User { User { name, age: 18, sex: String::from("male"), email, } }
|
struct更新语法
基于某个struct实例来创建一个新的实例时,可以使用struct更新语法进行创建,示例如下
1 2 3 4 5 6 7 8 9 10 11 12 13
| let user1 = User { name: String::from("Zhang San"), age: 28, sex: String::from("male"), email: String::from("zhangsan123@163.com"), };
let user2 = User { name: String::from("Li Si"), email: String::from("lisi456@163.com"), ..user1 };
|
struct数据所有权
示例中的name等元素使用了String而不是&str,则struct示例拥有其所有的数据,只要struct实例是有效的,name里面的字段数据也是有效的。
使用实例——计算长方形的面积
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #[derive(Debug)] struct Rectangle { width: u32, height: u32, }
fn cal_rectangle_area(rectangle: &Rectangle) -> u32 { rectangle.width * rectangle.height }
fn main() { let rectangle = Rectangle { width: 10, height: 50, };
println!("{:?}", rectangle); println!("rectangle area: {}", cal_rectangle_area(&rectangle)) }
|
输出结果如下:
1 2
| Rectangle { width: 10, height: 50 } rectangle area: 500
|
Tuple Struct
可定义类似tuple的sturct,称作tuple struct
Tuple Strcut整体有名称,但里面的元素没有名称
适用于想给整个tuple起名,并且它不同于其他tuple,而且又不需要给每个元素起名的场景
定义Tuple Struct
示例如下:
1 2 3 4 5
| strcut Color(i32, i32, i32) strcut Point(i32, i32, i32)
let black = Color(0, 0, 0) let origin = Point(0, 0, 0)
|
Unit-Like Struct
在rust中,没有任何字段的struct称作Unit-Like Struct
适用于需要在某个类型实现某个trait,但是在里面又没有想要存储的数据
struct的方法
方法与函数的相同之处:
方法与函数的不同之处:
- 方法在struct(或enum、trait对象)的上下文中进行定义,需要在impl块中定义方法;
- 方法的第一个参数时self,表示方法被调用的struct实例;
- 方法调用的运算符:object.func();
以计算长方形面积为例,实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #[derive(Debug)] struct Rectangle { width: u32, height: u32, }
impl Rectangle { fn cal_rectangle_area(&self) -> u32 { self.width * self.height } }
fn main() { let rectangle = Rectangle { width: 10, height: 50, };
println!("{:?}", rectangle); println!("rectangle area: {}", rectangle.cal_rectangle_area()) }
|
输出结果如下:
1 2
| Rectangle { width: 10, height: 50 } rectangle area: 500
|
关联函数
可以在在impl块里定义不把self作为第一个参数的函数,被称作关联函数,关联函数不是方法,例如String::from()
关联函数通常被用于构造器,示例如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| #[derive(Debug)] struct Rectangle { width: u32, height: u32, }
impl Rectangle { fn cal_rectangle_area(&self) -> u32 { self.width * self.height }
fn create_square(size: u32) -> Rectangle { Rectangle { width: size, height: size } } }
fn main() { let square = Rectangle::create_square(5); println!("{}", square.cal_rectangle_area()); }
|
输出如下:5
枚举类型
实现一个结构体struct,用于存储IP地址信息,示例如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #[derive(Debug)] enum IpAddrType { IPv4, IPv6, }
struct IpAddrInfo { ip_type: IpAddrType, addr: String, }
fn main() { let route = IpAddrInfo { ip_type: IpAddrType::IPv4, addr: String::from("127.0.0.1"), };
print!("{:?} {}", route.ip_type, route.addr); }
|
输出结果如下:
标准库中的IpAddr
枚举变体
将数据附加到枚举的变体中,示例如下:
1 2 3 4 5 6 7 8 9 10 11 12
| enum IpAddr { IPv4(u8, u8, u8, u8), IPv6(String), }
fn main() { let ipv4 = IpAddr::IPv4(127, 0, 0, 1); let ipv6 = IpAddr::IPv6(String::from("AA22:BB11:1122:CDEF:1234:AA99:7654:7410"));
println!("ipv4: {:?}", ipv4); println!("ipv6: {:?}", ipv6); }
|
输出结果如下:
1 2
| ipv4: IPv4(127, 0, 0, 1) ipv6: IPv6("AA22:BB11:1122:CDEF:1234:AA99:7654:7410")
|
Option枚举
定义在标准库中,在Prelude(预导入模块)中,描述了某个值可能存在(某种类型)或者不存在的情况
在标准库中的定义如下:
1 2 3 4
| enum Option<T> { Some(T), None, }
|
使用示例如下:
1 2 3 4 5 6
| fn main() { let some_num = Some(5); let some_str = Some("This a string."); let absent_num: Option<i32> = None; }
|
控制流运算符match
- match匹配必须穷举所有可能的值
- 可以使用通配符_,用于替代其他没列出的值,类似C语言switch/case中的default处理
示例如下,使用效果类似switch/case
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| enum Coin { Penny, Nickel, Dime, Quarter, }
fn value_in_cents(coin: Coin) -> u8 { match coin { Coin::Penny => 1, Coin::Nickel => 5, Coin::Dime => 10, Coin::Quarter => 25, } }
fn main() { let coin = Coin::Nickel; println!("{}", value_in_cents(coin)); }
|
绑定值的模式匹配
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| enum UsState { Alabama, Alaska, }
enum Coin { Penny, Nickel, Dime, Quarter(UsState), }
fn value_in_cents(coin: Coin) -> u8 { match coin { Coin::Penny => 1, Coin::Nickel => 5, Coin::Dime => 10, Coin::Quarter(state) => { println!("State quarter from {:?}", state); 25 } } }
fn main() { let coin = Coin::Quarter(UsState::Alaska); println!("{}", value_in_cents(coin)); }
|