繁体   English   中英

为什么我可以添加一个字符串和一个引用,而不是两个字符串? (E0308:类型不匹配)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM