下面是一个非常简单但具体的示例,它会产生一个我无法理解的编译错误:
use std::path::Path;
trait MyTrait<T> {
fn my_func(&self, t: T);
}
struct MyImpl {}
impl MyTrait<&Path> for MyImpl {
fn my_func(&self, t: &Path) {
println!("{:?}", t)
}
}
struct MyWrapper<T> {
inner: Box<dyn MyTrait<T>>
}
impl<T> MyWrapper<T> {
pub fn new(inner: Box::<dyn MyTrait<T>> ) -> Self {
Self { inner }
}
}
impl<T> MyTrait<T> for MyWrapper<T> {
fn my_func(&self, t: T) {
self.inner.my_func(t);
}
}
fn foobar() {
let the_impl = MyImpl{};
//let the_impl = MyWrapper::new(Box::new(the_impl)); // (*)
for entry in walkdir::WalkDir::new("blah") {
let entry = entry.unwrap();
let path = entry.path(); // <== here
the_impl.my_func(path);
}
}
当标记为(*)的行被注释时,一切正常.然而,如果没有注释,编译器会抱怨entry
不够长,请参见标记为"here"的行.
我不明白包装器是如何碰巧改变路径被borrow 的方式的.
EDIT个
正如@jmb下面指出的,这与Path
无关,简单的&str
也会出现同样的问题,例如:
impl MyTrait<&str> for MyImpl {
fn my_func(&self, t: &str) {
println!("{:?}", t)
}
}
fn foobar_str() {
let the_impl = MyImpl{};
let the_impl = MyWrapper::new(Box::new(the_impl));
{
let s = String::from("blah").clone();
the_impl.my_func(&s as &str); // <== same error
}
}
EDIT2个
对于任何遇到这个问题的人,有一个可行的解决方案,可以按照我的回答中所描述的那样修改特征.