类型 `&str` 没有实现 Trait [E0277]。

3
我有一个针对str的特质定义,在这个定义中,我定义了一个需要 &self 的函数。如果我从主函数中对静态 &str 调用此函数,则一切正常。但是,如果我从接受特质对象参数的函数中调用同样的函数,则会出现以下错误:MyTrait is not implemented for the type&str[E0277] 我已经找到了一个解决方法,但我不清楚成本,我是否正在复制字符串?
#[derive(Debug)]
struct Thingie{
 pub name: String, // rather than &a str for Thingie<'a>
}

trait MyTrait{
    fn to_thingie(&self)->Option<Thingie>;
}

impl MyTrait for str{
    fn to_thingie(&self)->Option<Thingie>{
        println!(">>MyTrait for str");
        Some(Thingie{name:self.to_string()})
    }
}


fn method_on_trait <T:MyTrait> (thing:T){
   let v= thing.to_thingie();
   println!("Method on trait: {:?}",v);
}

fn main(){
 println!("in main: {:?}","test".to_thingie());
 method_on_trait("test");
}

//TODO: Uncomment this for a fix. WHY?
//Is this creating a copy of the string or just transfering the binding?
// impl<'a> MyTrait for &'a str{
//     fn to_thingie(&self)->Option<Thingie>{
//         println!(">>MyTrait<'a> for &'a str");
//         (*self).to_thingie()
//     }
// }

我不知道这是否是良好的礼仪,但这是此代码片段的 Rust Playground 链接:https://play.rust-lang.org/?gist=10bd0d565e9106e1900c&version=stable - Florian Doyon
1个回答

3
你需要告诉method_on_trait它可以处理未定大小的类型,并向其传递对T的引用(而不是直接传递T,此时T可能没有大小并且无法按值传递)。 第一种方法是将?Sized“限制”添加到T中,第二种方法是将thing设置为&T
fn method_on_trait<T: MyTrait + ?Sized> (thing: &T) {
   let v = thing.to_thingie();
   println!("Method on trait: {:?}",v);
}

这里发生的情况是,MyTrait 只为 str 实现,而 str 是一种无大小限制的类型。你试图在主函数中将 "test"(一个 &'static str)传递给 method_on_trait,这导致了 E0277 错误。
你的注释代码正在为 &str 实现 MyTrait,这使得原始代码编译通过,因为你确实将 &str 传递给了 method_on_trait。没有复制原始字符串,&str 基本上只是 指向它的指针加上长度信息

谢谢,我完全忘记了“Sized”特质。 - Florian Doyon
我想感谢@Pablo提供非常清晰详细的解释。这对我非常有帮助。 - Florian Doyon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接