简体   繁体   English

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

[英]Why can I add a String and a reference, but not two Strings? (E0308: Mismatched types)

I'm trying to write a trait on the String type that will allow it to concatenate Bar to any other string.我正在尝试在String类型上编写一个特征,以允许它将Bar连接到任何其他字符串。

I know what the solution is but I'm not sure why it works.我知道解决方案是什么,但我不确定它为什么会起作用。 Could someone please explain the theory underlying the syntax for me?有人可以为我解释一下语法背后的理论吗?

// 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")
}

The full script is below.完整的脚本如下。

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")
        );
    }
}

The + operator is sugar for the add method of the std::ops::Add trait, and the implementation for String is: +运算符是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
    }
}

That is, the right hand side of the + must be &str when the left hand side is a String .也就是说,当左侧是String时, +的右侧必须是&str

However, due to deref coercion for function arguments, you can also pass a &String instead of a &str , because String implements Deref<Target = str> .但是,由于function arguments的 deref 强制,您也可以传递&String而不是&str ,因为String实现Deref<Target = str>

It's worth noting that a better "fix" for the exact code you provided is to avoid allocating a temporary String altogether, since "Bar" is already a &str :值得注意的是,对于您提供的确切代码,更好的“修复”是避免完全分配临时String ,因为"Bar"已经是&str

fn append_bar(self) -> String {
    self + "Bar"
}

See also: Why is it discouraged to accept a reference to a String (&String), Vec (&Vec), or Box (&Box) as a function argument?另请参阅: 为什么不鼓励接受对字符串 (&String)、Vec (&Vec) 或框 (&Box) 的引用作为 function 参数?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我不能将两个字符串连接在一起,但我可以连接一个字符串和一个 &str? - Why can't I concatenate two Strings together, but I can concatenate a String and a &str? 如何添加两个字符串? - How can I add two strings? c#字符串是引用类型-为什么当我更改引用A的值时,引用B不变? - c# strings are reference types - why when i change reference A's value, reference B doesn't change? C ++ / CLI:为什么我不能通过引用传递字符串? - C++/CLI : Why can't I pass Strings by reference? 如何组合我的两个字符串以将其添加到前一个字符串? - How do I combine my two strings to add it on to the previous string? 为什么我不能使用运算符重载来添加两个字符串? - why i'm not able to add two strings using operator overloading? Javascript:如何在不转换为数字的情况下添加两个字符串? - Javascript: How can I add two strings without converting into numbers? 如何获得两个已知字符串之间的字符串? - How can I get a string inbetween two known strings? 为什么我不能在汇编中打印两个不同的字符串? - Why can't I print two different strings in assembly? 如何在python中找到两个字符串之间的字符串并打印出来? - How can I find and print a string between two strings in python?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM