rust - 如何实现特质

标签 rust traits

我正在尝试为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"

Playground

关于rust - 如何实现特质,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61378351/

相关文章:

rust - 如何修复 : expected concrete lifetime, 但找到绑定(bind)的生命周期参数

rust - 为什么 Rust 在 LLVM IR 闭包环境中将闭包捕获的 i64 存储为 i64*s?

rust - Rust:特征中的类型引用

Scala:在模式匹配中混合特征和案例类

rust - 为大数组类型实现调试特性

rust - &()语法的目的是什么?

syntax - 如何以干净的方式混合 bool 比较和 'if let' 语句?

json - 我如何进行模式匹配以获得 serde_json 已解析的数字?

php - 使用 Laravel RouteNotifcationForMail() 发送到多个电子邮件地址?

带有引用的 Rust 泛型 AddAssign