如何实现特征

Con*_*ell 0 traits rust

我想实现一个所谓的新特征AppendBarString。它的唯一功能是append_bar.

根据我的理解,self应该是一个String的实例。

trait AppendBar {
    fn append_bar(self) -> Self;
}

impl AppendBar for String {
    fn append_bar(self) -> Self{
        self.clone().push_str("Bar")
    }
}

fn main() {
    let s = String::from("Foo");
    let s = s.append_bar();
    println!("s: {}", s);  // "s: FooBar"
}
Run Code Online (Sandbox Code Playgroud)

这显然不是这种情况,因为我收到以下错误:

error[E0308]: mismatched types
  --> exercises/traits/traits1.rs:18:9
   |
17 |     fn append_bar(self) -> Self{
   |                            ---- expected `std::string::String` because of return type
18 |         self.clone().push_str("Bar")
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `std::string::String`, found `()`

Run Code Online (Sandbox Code Playgroud)

谁能帮助我理解我的误解?

log*_*yth 7

17 |     fn append_bar(self) -> Self{
   |                            ---- expected `std::string::String` because of return type
18 |         self.clone().push_str("Bar")
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `std::string::String`, found `()`
Run Code Online (Sandbox Code Playgroud)

是说它期望append_bar返回 a String,但self.clone().push_str("Bar")计算结果为()单位类型的类型。编译器错误是正确的,因为push_str函数的类型是fn push_str(&mut self, string: &str),请注意它没有返回类型,而是改变了它的Self参数。

相反,您需要推入字符串然后返回字符串,例如

impl AppendBar for String {
    fn append_bar(mut self) -> Self{
        self.push_str("Bar");
        self
    }
}
Run Code Online (Sandbox Code Playgroud)

我也删除了,.clone()因为它没有必要。append_bar已经接受self并因此获得字符串值的所有权,因此您可以推入它并返回它而无需克隆它。