我如何才能向后迭代? [英] How can I iterate over a backwards range?

查看:11
本文介绍了我如何才能向后迭代?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建pub fn sing(start: i32, end: i32) -> String,它返回对startend之间的每个数字重复调用pub fn verse(num: i32) -> String的结果的串联字符串。

我已经在谷歌上搜索了答案,似乎Rust String concatenation回答了我的问题,如果我甚至用playground编写代码,它都可以工作,但是:

我的代码:

pub fn verse(num: i32) -> String {
    match num {
        0 => "No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.
".to_string(),
        1 => "1 bottle of beer on the wall, 1 bottle of beer.
Take it down and pass it around, no more bottles of beer on the wall.
".to_string(),
        2 => "2 bottles of beer on the wall, 2 bottles of beer.
Take one down and pass it around, 1 bottle of beer on the wall.
".to_string(),
        num => format!("{0} bottles of beer on the wall, {0} bottles of beer.
Take one down and pass it around, {1} bottles of beer on the wall.
",num,(num-1)),
    }
}

pub fn sing(start: i32, end: i32) -> String {
    (start..end).fold(String::new(), |ans, x| ans+&verse(x))
}

问题是

#[test]
fn test_song_8_6() {
    assert_eq!(beer::sing(8, 6), "8 bottles of beer on the wall, 8 bottles of beer.
Take one down and pass it around, 7 bottles of beer on the wall.

7 bottles of beer on the wall, 7 bottles of beer.
Take one down and pass it around, 6 bottles of beer on the wall.

6 bottles of beer on the wall, 6 bottles of beer.
Take one down and pass it around, 5 bottles of beer on the wall.
");
}

失败,beer::sing(8,6)返回""

推荐答案

您的问题与字符串连接无关。这与8..6是一个空迭代器的事实有关,因为范围只向前迭代。由于8 >= 6,迭代器在第一次调用next时生成None

fn main() {
    for i in 8..6 {
        println!("{}", i); // never reached
    }
}

可以通过交换startend并调用rev()向后迭代来修复此问题。

fn main() {
    for i in (6..8).rev() {
        println!("{}", i);
    }
}

然而,还有一个问题。在范围start..end中,start是包含的,但end是排除的。例如,上面的代码打印768不打印。请参见How do I include the end value in a range?

将所有这些放在一起,sing应该如下所示:

pub fn sing(start: i32, end: i32) -> String {
    (end..=start)
        .rev()
        .fold(String::new(), |ans, x| ans + &verse(x))
}
注意:您的测试仍然失败,因为它预期每行之间有两个换行符,但您的代码只生成一个换行符。我会让你来解决这件事的。🙂

这篇关于我如何才能向后迭代?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆