简体   繁体   English

添加两个字符串时如何修复不匹配的类型?

[英]How to fix mismatched types when adding two Strings?

With a list input of &str , I'm trying to create a String which contains a proverb based on the inputs.使用&str的列表输入,我试图创建一个包含基于输入的谚语的String

Instead of String::from I also tried .to_string() but that doesn't seem to help matters.而不是String::from我也尝试了.to_string()但这似乎没有帮助。

pub fn build_proverb(list: &[&str]) -> String {
    let mut string = String::from(format!("For want of a {} the {} was lost.\n", list[0], list[1]));

    if list.len() > 2 {
        (3..list.len() + 1).map(|x| string = string + String::from(format!("For want of a {} the {} was lost.\n", list[x], list[x-1])));
    }

    string = string + &(format!("And all for the want of a {}.", list[0])).to_string();

    return string.to_string();
}

The error is:错误是:

error: mismatched types expected &str, found struct 'std::string::String'.

This is on the String::from(format!("For want of a {} the {} was lost.\\n", list[x], list[x-1])) line.这是在String::from(format!("For want of a {} the {} was lost.\\n", list[x], list[x-1]))行上。

What's confusing to me is that I'm adding a String to a String - why is it expecting a &str ?让我感到困惑的是,我将一个String添加到一个String ——为什么它需要一个&str

format! already returns a String , so there's no need for String::from(format!(...)) , and it's also an error because it expects a &str , not a String returned by format!已经返回一个String ,所以不需要String::from(format!(...)) ,它也是一个错误,因为它需要一个&str ,而不是format!返回的String format! . .

You'll also get an error in the lambda:你还会在 lambda 中得到一个错误:

string = string + String::from(format!(...))

...even if you remove String::from , because it's not possible to add two String s like that, but it is possible to add a String and a &str , so I think you should borrow like this: ...即使您删除String::from ,因为不可能像这样添加两个String ,但是可以添加一个String和一个&str ,所以我认为您应该像这样借用:

string = string + &format!(...)

The same goes for this line:这一行也是如此:

string = string + &(format!("And all for the want of a {}.", list[0])).to_string();

Moreover, your usage of map won't actually execute the lambda for each element of the range.此外,您对map的使用实际上不会为范围的每个元素执行 lambda。 It'll just create a Map iterator , over which you'll have to iterate with a loop to actually make it execute the lambda, so you could as well iterate over the range itself and modify your string in the loop. 它只会创建一个Map iterator ,你必须用一个循环迭代它才能真正执行 lambda,所以你也可以迭代范围本身并在循环中修改你的字符串。

I'm also not terribly sure about why you're returning string.to_string() when you could've returned string itself.我也不太确定为什么在您可以返回string本身时返回string.to_string()


I also think you have an off-by-one error in your range, so after fixing that, I ended up with this:我也认为你的范围内有一个错误,所以在解决这个问题之后,我最终得到了这个:

fn do_it(list: Vec<&str>) -> String {
    let mut string = format!("For want of a {} the {} was lost.\n", list[0], list[1]);

    // BTW, you don't need this `if` statement because empty ranges, like `2..2`, are perfectly fine
    if list.len() > 2 {
        // These ranges do not include `list.len()`, so your program won't panic, because this index doesn't exist
        for x in 2 .. list.len() {
            string += &format!("For want of a {} the {} was lost.\n", list[x], list[x-1])
        }
    }

    string + &format!("And all for the want of a {}.", list[0])  // Return the result of concatenation
}

fn main() {
    let list = vec!["something", "test", "StackOverflow"];
    let result = do_it(list);

    println!("The result is: {}", result)
}

Output (it works, but your post doesn't say what it should output, so I can't say if it's the correct result):输出(它有效,但你的帖子没有说明它应该输出什么,所以我不能说它是否是正确的结果):

The result is: For want of a something the test was lost.
For want of a StackOverflow the test was lost.
And all for the want of a something.

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

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