[英]How to implement a trait
我正在尝试为String
实现一个名为AppendBar
的新特征。 它唯一的 function 是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 `()`
谁能帮我理解我的误解?
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
返回一个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
}
}
我也删除了.clone()
因为它不是必需的。 append_bar
已经接受了self
并因此获得了字符串值的所有权,因此您可以将其推入并返回它,而无需克隆它。
@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"
(这与@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"
如果您希望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"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.