类型系统
Rust类型系统特点
三个标准
- 隐式转换
- 检查时机
- 多态支持
类型分类
原生类型
组合类型
自定义组合类型
小例子
常量
常量定义使用
const PI: f64 = std::f64::consts::PI; static E: f32 = std::f32::consts::E; fn main() { const V: u32 = 10; static V1: &str = "hello"; println!("PI: {}, E: {}, V {}, V1: {}", PI, E, V, V1); }
类型推导
Rust编译器可以从上下文自动推导类型
use std::collections::BTreeMap; fn main() { let mut map = BTreeMap::new(); // 没有这一行就缺少自动推导信息 // map.insert("hello", "world"); println!("map: {:?}", map); }
把第 5 行这个作用域内的 insert 语句注释去掉,Rust 编译器就会报错:“cannot infer type for type parameter K”。
Rust编译器不能获取足够上下文信息时,就需要明确类型
- 无法自动推导collect返回什么类型
fn main() { let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; let even_numbers = numbers .into_iter() .filter(|n| n % 2 == 0) .collect(); println!("{:?}", even_numbers); }
- 给even_numbers添加类型声明即可
fn main() { let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; let even_numbers: Vec<_> = numbers .into_iter() .filter(|n| n % 2 == 0) .collect(); println!("{:?}", even_numbers); }
这里编译器只是无法推断出集合类型,但集合类型内部元素的类型,还是可以根据上下文得出,所以我们可以简写成 Vec<_>
- 也可以让 collect 返回一个明确的类型
fn main() { let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; let even_numbers = numbers .into_iter() .filter(|n| n % 2 == 0) .collect::<Vec<_>>(); println!("{:?}", even_numbers); }
这里在泛型函数后使用 :: 来强制使用类型 T,这种写法被称为 turbofish
Turbofish
一个对 IP 地址和端口转换的例子
use std::net::SocketAddr; fn main() { let addr = "127.0.0.1:8080".parse::<SocketAddr>().unwrap(); println!("addr: {:?}, port: {:?}", addr.ip(), addr.port()); }