Table of contents
Open Table of contents
as:原始类型强转
编译器内置的转换,仅限原始类型(整数、浮点、指针),和任何 trait 无关。
let x: i32 = 42;
let y: f64 = x as f64; // 整数 → 浮点
let z: u8 = x as u8; // i32 → u8(截断,只保留低 8 位)
let b: u8 = 256_i32 as u8; // 得到 0!静默截断,不报错
let c: i8 = 200_u8 as i8; // 得到 -56!溢出,不报错
let p = &x as *const i32; // 引用 → 裸指针
let n = p as usize; // 指针 → 整数
不能做的事:
let s: String = 42 as String; // 编译错误!String 不是原始类型
let p: Player = row as Player; // 编译错误!自定义类型不行
注意:as 会静默丢数据,是 Rust 里少数不安全的操作之一。
From / Into:trait 方法,类型安全
// From:从另一个类型构造自己
let s: String = String::from(42); // 调 From<i32> for String
let id: PlayerId = PlayerId::from(42); // 调 From<u32> for PlayerId
// Into:把自己转成另一个类型(From 的反向,自动生成)
let s: String = 42.into(); // 等价于 String::from(42)
let id: PlayerId = 42_u32.into(); // 等价于 PlayerId::from(42)
// ? 操作符内部也是调 From::from
let err: AppError = sqlx_error.into(); // 或者 ? 自动调用
和 as 的关系:没有任何关系。as 不会调用 From/Into。
TryFrom / TryInto:可能失败的转换
let n: u8 = u8::try_from(256_i32); // Err!256 超出 u8 范围
let n: u8 = 256_i32 as u8; // 0!as 静默截断
// 所以实际项目中优先用 TryFrom
let port: u16 = raw_port.try_into()?; // 超出范围会返回 Err
Turbofish ::<>:告诉编译器泛型类型参数
不是类型转换,是泛型调用的显式类型标注。
// parse 的签名:fn parse<F: FromStr>(&self) -> Result<F, F::Err>
// 编译器需要知道 F 是什么类型
// 方式 1:从变量类型标注推断
let n: u32 = "42".parse().unwrap(); // 编译器从 `: u32` 推断 F = u32
// 方式 2:turbofish 直接指定
let n = "42".parse::<u32>().unwrap(); // 直接告诉 parse:F = u32
// 没有任何类型信息时:
let n = "42".parse().unwrap(); // 编译错误!F 是什么?
常见使用场景:
// collect:编译器不知道你要收集成什么容器
let nums = vec![1, 2, 3];
let strings = nums.iter().map(|n| n.to_string()).collect::<Vec<String>>();
// channel:编译器不知道传什么类型
let (tx, rx) = tokio::sync::mpsc::channel::<Message>(32);
// 链式调用中间无法标注类型,只能用 turbofish
let result = "3.14".parse::<f64>().unwrap().sqrt();
叫 turbofish 是因为 ::<> 长得像一条鱼。社区绰号,不是官方术语。
对比
语法 是什么 能做什么 会丢数据吗
──────────────────────────────────────────────────────────────────────
as 编译器内置强转 原始类型互转(数值、指针) 会,静默截断
From/Into trait 方法调用 任何类型间的安全转换 不会
TryFrom/Into trait 方法调用 可能失败的转换,返回 Result 不会,失败返回 Err
::<> turbofish 类型标注语法 告诉编译器泛型参数是什么 不涉及转换