仅使用 for 循环体内的条件将字符串与空格连接起来

Concatenate strings with spaces using only conditionals inside of a for-loop body

我正在做 Rust Koans 并且卡在这个问题上:

#[test]
fn for_loops_two() {
    let words: [&'static str; 3] = ["I", "love", "Rust"];
    let space: &str = " ";
    let mut sentence: String = String::new();
    for word in words.iter() {
        // __
    }

    println!("{:?}", sentence);
    assert!(sentence == "I love Rust".to_string());
}

我知道我需要连接字符串,但这会失败:

#[test]
fn for_loops_two() {
    let words: [&'static str; 3] = ["I", "love", "Rust"];
    let mut sentence: String = String::new();
    for word in words.iter() {
        sentence.push_str(word);
    }

    println!("{:?}", sentence); // "ILoveRust"
    assert!(sentence == "I love Rust".to_string());
}

我可以在每次迭代后添加一个space:

#[test]
fn for_loops_two() {
    let words: [&'static str; 3] = ["I", "love", "Rust"];
    let space: &str = " ";
    let mut sentence: String = String::new();
    for word in words.iter() {
        sentence.push_str(word);
        sentence.push_str(space);
    }

    println!("{:?}", sentence); // "I Love Rust "
    assert!(sentence == "I love Rust".to_string());
}

这也会失败,因为最终迭代将添加一个 space。

我想如果我们在最后一次迭代,我可以写一个条件,但我正在努力使语法正确。此外,我觉得所有这些都有更好的解决方案,我只是想不出语法。

如何使上面的断言在循环中通过条件传递而不在最后一次迭代中添加 space?

您可以使用 slice::join:

#[test]
fn for_loops_two() {
    let words: [&'static str; 3] = ["I", "love", "Rust"];

    let sentence = words.join(" ");

    assert!(sentence == "I love Rust".to_string());
}

关于链接 SliceConcatExt 特征的注释:它在文档中被列为不稳定,但 方法 是稳定的 - 以上在当前稳定下编译得很好Rust 版本。

如果你宁愿坚持 koan 的约束并使用 for 循环,你可以按照你的建议使用 if(弄清楚你是否在最后使用 enumerate), or pop 字符串末尾的最后一个 space:

#[test]
fn for_loops_two_with_len_check() {
    let words: [&'static str; 3] = ["I", "love", "Rust"];
    const SPACE: char = ' ';
    let number_of_words = words.len();
    let mut sentence = String::new();

    for (i, word) in words.iter().enumerate() {
        sentence.push_str(word);
        if i < number_of_words-1 {
            sentence.push(SPACE);
        }
    }

    assert!(sentence == "I love Rust".to_string());
}


#[test]
fn for_loops_two_with_pop() {
    let words: [&'static str; 3] = ["I", "love", "Rust"];
    const SPACE: char = ' ';
    let mut sentence = String::new();

    for word in words.iter() {
        sentence.push_str(word);
        sentence.push(SPACE);
    }
    let _ = sentence.pop();

    assert!(sentence == "I love Rust".to_string());
}

有点晚了,但这是一个只修改循环内块的解决方案:

#[test]
fn for_loops_two() {
    let words: [&'static str; 3] = ["I", "love", "Rust"];
    let mut sentence: String = String::new();
    for word in words.iter() {
        if sentence != "".to_string() {
            sentence.push(' ')
        }
        sentence.push_str(word)
    }
    println!("{:?}", sentence);
    assert!(sentence == "I love Rust".to_string());
}