外观
雷区 6:E0308 类型对不上
报错码:E0308
症状
rust
fn main() {
let input = String::from("42");
let number: u32 = input.parse();
println!("{}", number);
}编译输出
text
error[E0308]: mismatched types
--> src/main.rs:3:23
|
3 | let number: u32 = input.parse();
| --- ^^^^^^^^^^^^^ expected `u32`, found `Result<_, _>`
| |
| expected due to this
|
= note: expected type `u32`
found enum `Result<_, _>`
help: consider using `Result::expect` to unwrap the `Result<_, _>` value, panicking if the value is a `Result::Err`
|
3 | let number: u32 = input.parse().expect("REASON");
| +++++++++++++++++诊断
类型对不上,这是新手第一周就撞、老手每天都会撞的报错——也是最"好懂"的报错:左边要 u32,右边给了 Result<_, _>,对不上。
为什么 parse() 返回 Result?因为"把文字变成数字"可能失败("abc" 变不了数字,第 2 章)。Rust 不让你假装它一定成功——let number: u32 = input.parse(); 想跳过"可能失败"这一步,编译器不答应。
E0308 的高频变体:
rust
let x: u32 = some_f64; // 数字类型不匹配(数字间不会自动转换!)
let s: String = some_str; // String 和 &str 不一样
let v: Vec<i32> = some_vec; // 泛型参数不匹配
let n: u32 = "42".parse(); // 忘记处理 Result(本雷区)重点:数字不自动转换
Rust 里 u32 和 f64、i32 和 u64 不会自动互转——想转,用第 9 章的 as:some_f64 as u32。这是 Rust 比很多语言"严格"的地方:类型转换要明说,免得精度悄悄丢。
解药
解药一:处理 Result(parse 的标配)——拆信封或让它炸:
rust
fn main() {
let input = String::from("42");
let number: u32 = input.parse().expect("要数字!");
println!("{}", number);
}或者用第 8 章的 match 优雅处理。
解药二:数字转换用 as(明确、自愿):
rust
fn main() {
let score: f64 = 9.7;
let rounded: u32 = score as u32; // 9.7 → 9(小数直接砍掉)
println!("{}", rounded);
}解药三:String 与 &str——按第 3 章的规矩:拥有用 String,借看用 &str:
rust
fn main() {
let owned = String::from("hello");
let borrowed: &str = &owned; // &String 自动变成 &str
println!("{}", borrowed);
}预防
- E0308 的读法:先看
expected和found各是什么,差在哪一层(类型?泛型参数?是没拆的 Result?) - 看到
Result<_, _>出现在expected/found里 → 十有八九是忘了处理可能失败的操作(parse、读文件、网络) - Rust 不做隐式数字转换:跨类型运算/赋值,主动
as或先想清楚类型设计 {:?}调试打印 + 类型标注,是排查 E0308 的两把钥匙:打印出来看形状,标注上去看类型