如何实现特质

我正在尝试实现一个新的特质,叫做 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 `()`

谁能帮我理解一下我的误解?

解决方案:

@loganfsmyth的回答解释了为什么你会得到这个错误信息。有三种方法可以解决这个问题,这取决于你的期望值 append_bar:

掌握自主权

如果你期望 append_bar 来返回修改后的字符串,并且不希望调用者在之后能够使用输入的字符串。

impl AppendBar for String {
    fn append_bar (mut self) -> Self {
        self.push_str ("Bar");
        self
    }
}
let s1 = String::from ("Foo");
let s2 = s1.append_bar();
// println!("s1: {}", s1);    // Error: s1 is no longer usable at this point
println!("s2: {}", s2);    // Prints "FooBar"

Playground

这和@loganfsmyth的答案是一样的)。

借用并克隆

如果你期望 append_bar 来返回修改后的字符串,并希望调用者之后能够继续使用原来的输入字符串。

impl AppendBar for String {
    fn append_bar (&self) -> Self {
        let mut s = self.clone();
        s.push_str ("Bar");
        s
    }
}
let s1 = String::from ("Foo");
let s2 = s1.append_bar();
println!("s1: {}", s1);    // Prints "Foo"
println!("s2: {}", s2);    // Prints "FooBar"

Playground

原地变异

如果你期望 append_bar 用修改后的字符串替换输入。

impl AppendBar for String {
    fn append_bar (&mut self) {
        self.push_str ("Bar");
    }
}
let mut s1 = String::from ("Foo");
s1.append_bar();
println!("s1: {}", s1);    // Prints "FooBar"

游乐场

给TA打赏
共{{data.count}}人
人已打赏
未分类

在c# NETCore中访问具有构造函数的类的方法,并使用IOptions<>。

2022-9-10 15:46:19

未分类

在aws中,当服务的健康状况下降时,发送SNS通知。

2022-9-10 15:46:21

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索