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