Объединить строки с пробелами, используя только условные выражения внутри тела цикла for - PullRequest
0 голосов
/ 24 марта 2019

Я делаю 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());
}

Я могу добавить пробел после каждой итерации:

#[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());
}

Это также не удастся, потому что последняя итерация добавит пробел.

Полагаю, я мог бы написать условное выражение, если мы находимся на последней итерации, но я пытаюсь получить правильный синтаксис. Более того, я чувствую, что для всего этого есть гораздо лучшее решение, и я просто не могу понять синтаксис.

Как сделать вышеупомянутое утверждение с условием в цикле, чтобы не добавить пробел на последней итерации?

1 Ответ

0 голосов
/ 24 марта 2019

Вы можете использовать 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.

Если вы предпочитаете придерживаться ограничений коана и используете цикл for, вы можете использовать либо if как вы предлагаете (выясните, используете ли вы в конце enumerate) или pop последний пробел от конца строки:

#[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());
}
...