首页 > 解决方案 > 如何实现一个特征

问题描述

我正在尝试实现一个名为AppendBar. String它的唯一功能是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"
}

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

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 `()`

谁能帮我理解我的误解?

标签: rusttraits

解决方案


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 `()`

是说它期望append_bar返回 a String,但self.clone().push_str("Bar")计算结果为()unit 类型。编译器错误是正确的,因为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
    }
}

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


推荐阅读