![](/img/trans.png)
[英]Why can't I concatenate two Strings together, but I can concatenate a String and a &str?
[英]Why can I add a String and a reference, but not two Strings? (E0308: Mismatched types)
我正在尝试在String
类型上编写一个特征,以允许它将Bar
连接到任何其他字符串。
我知道解决方案是什么,但我不确定它为什么会起作用。 有人可以为我解释一下语法背后的理论吗?
// problematic code
// error[E0308]: mismatched types
// rustc --explain E0308
fn append_bar(self) -> String {
self + String::from("Bar")
}
// solution
fn append_bar(self) -> String {
self + &String::from("Bar")
}
完整的脚本如下。
trait AppendBar {
fn append_bar(self) -> String;
}
impl AppendBar for String {
fn append_bar(self) -> String {
self + String::from("Bar")
}
}
fn main() {
let s = String::from("Foo");
let s = s.append_bar();
println!("s: {}", s);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn is_FooBar() {
assert_eq!(String::from("Foo").append_bar(), String::from("FooBar"));
}
#[test]
fn is_BarBar() {
assert_eq!(
String::from("").append_bar().append_bar(),
String::from("BarBar")
);
}
}
+
运算符是std::ops::Add
trait 的add
方法的糖, String
的实现是:
impl<'_> Add<&'_ str> for String {
type Output = String;
fn add(mut self, other: &str) -> String {
self.push_str(other);
self
}
}
也就是说,当左侧是String
时, +
的右侧必须是&str
。
但是,由于function arguments的 deref 强制,您也可以传递&String
而不是&str
,因为String
实现Deref<Target = str>
。
值得注意的是,对于您提供的确切代码,更好的“修复”是避免完全分配临时String
,因为"Bar"
已经是&str
:
fn append_bar(self) -> String {
self + "Bar"
}
另请参阅: 为什么不鼓励接受对字符串 (&String)、Vec (&Vec) 或框 (&Box) 的引用作为 function 参数?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.