外观
雷区 9:E0599 方法找不到(忘了 use trait!)
报错码:E0599
症状
rust
mod animals {
pub trait Greeter {
fn greet(&self) -> String;
}
impl Greeter for String {
fn greet(&self) -> String {
format!("{}!", self)
}
}
}
fn main() {
let name = String::from("旺财");
println!("{}", name.greet());
}编译输出
text
error[E0599]: no method named `greet` found for struct `String` in the current scope
--> src/main.rs:15:25
|
3 | fn greet(&self) -> String;
| ----- the method is available for `String` here
...
15| println!("{}", name.greet());
| ^^^^^
|
= help: items from traits can only be used if the trait is in scope
help: there is a method `get` with a similar name, but with different arguments
--> ...诊断
方法明明存在("the method is available for String here"),却找不到——因为 trait 没请进门。
greet 定义在 Greeter trait 里,而 Greeter 住在 animals 模块里。第 6 章的私有性 + 第 9 章的 trait: trait 定义的方法,要 use 了 trait 才能调用——就像动物的能力要"领证"才能用。
报错里有两句金句:
the method is available for String here:"方法在这里确实存在"——不是没有,是没进门items from traits can only be used if the trait is in scope:"trait 的东西,只有 trait 在作用域里才能用"
真实项目里,E0599 的三大来源:
- 忘了 use trait(本雷区):
use animals::Greeter;一加就好 - 拼写错误:方法名打错(
greet→gret) - 类型不对:在错误的类型上调用(比如对
&String调需要String的方法)
解药
解药一:把 trait 请进门(最经典):
rust
mod animals {
pub trait Greeter {
fn greet(&self) -> String;
}
impl Greeter for String {
fn greet(&self) -> String {
format!("{}!", self)
}
}
}
use animals::Greeter;
fn main() {
let name = String::from("旺财");
println!("{}", name.greet());
}解药二:用完整路径调用(不想 use 时):
rust
println!("{}", animals::Greeter::greet(&name));解药三:检查拼写和类型——报错如果提示"there is a method get with a similar name"(有个名字很像的 get),说明你拼错了;如果类型不对,先 {:?} 打印看类型。
真实世界的 E0599 高频区
- 忘了
use std::io::Read;用read_to_string - 忘了
use std::iter::Sum;用.sum()(老版本 Rust) - 自定义 trait 放一个模块、用的人在另一个模块,忘了 use
- 第三方库(serde、clap)的 trait 方法,都要先 use 才生效
预防
- E0599 的三连问:①use 了吗?(最常见!)②拼写对吗?③类型对吗?
- "方法存在却找不到" → 优先怀疑 trait 没进门:报错里的
the method is available for ... here就是在提示你"它在这儿呢,你得先 use" - 写模块化代码时(第 6 章),自定义 trait 放模块里,记得在调用处 use;公共 API 库里,把 trait 和类型一起 re-export(
pub use),用户一个 import 全搞定