我遇到的错误
直接使用 Error,没有使用 dyn
1fn run(config: Config) -> Result<(), dyn std::error::Error> {
2 let contents = std::fs::read_to_string(config.file_path).expect(
3 ...
4 Ok(())
官方解释,是你要求返回一个实现了某特质的对象,但是该对象并没有实现该特质。
You tried to use a type which doesn’t implement some trait in a place which expected that trait.
其实编译器给出的报错比较接近:
1error[E0277]: the size for values of type `(dyn std::error::Error + 'static)` cannot be known at compilation time
2 --> src/main.rs:18:27
3 |
418 | fn run(config: Config) -> Result<(), dyn std::error::Error> {
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
它说,dyn std::error::Error 的大小在编译器无法确定,因此我们可以使用 Box
std::sync::mpsc::Receiver<Job>
cannot be shared between threads safely
Receiver 没有实现某些多线程必须的特质,因此报错。
1fn new(id: usize, receiver: mpsc::Receiver<Job>) -> Self
改成
1fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Self
官方其它举例如下:
1// 声明一个 Foo 特质,有一个 bar 方法
2trait Foo {
3 fn bar(&self);
4}
5
6// 声明一个函数,消费实现了 Foo 特质的对象
7fn some_func<T: Foo>(foo: T) {
8 foo.bar();
9}
10
11fn main() {
12 // 给这个函数传递 i32 类型, 它没有实现 Foo 特质
13 some_func(5i32); // 报错 error: the trait bound `i32 : Foo` is not satisfied
14}
要修复这个问题,你需要对入参做一些检查,例如:
1trait Foo {
2 fn bar(&self);
3}
4
5// 为 i32 类型实现特质
6impl Foo for i32 {
7 fn bar(&self) {}
8}
9
10fn some_func<T: Foo>(foo: T) {
11 foo.bar(); // 现在可以使用了
12}
13
14fn main() {
15 some_func(5i32); // ok!
16}
另一例更常见:
1fn some_func<T>(foo: T) {
2 println!("{:?}", foo); // 报错 error: the trait `core::fmt::Debug` is not
3 // implemented for the type `T`
4}
5
6fn main() {
7 // We now call the method with the i32 type,
8 // which *does* implement the Debug trait.
9 some_func(5i32);
10}
尽管 i32 类型实现了 Debug 特质,但是编译器仍然会报错,因为它必须考虑全部情况:万一你没有传递正确的类型呢?
所以,可以做如下限制:
use std::fmt;
// 限制入参,必须实现 Debug 特质
fn some_func<T: fmt::Debug>(foo: T) {
println!("{:?}", foo);
}
fn main() {
// Calling the method is still fine, as i32 implements Debug.
some_func(5i32);
// This would fail to compile now:
// struct WithoutDebug;
// some_func(WithoutDebug);
}