代码之家  ›  专栏  ›  技术社区  ›  George Griffin

为什么我不能创建一个变量范围?[复制品]

  •  0
  • George Griffin  · 技术社区  · 6 年前

    我试图创造 pub fn sing(start: i32, end: i32) -> String 返回调用结果的连接字符串 pub fn verse(num: i32) -> String 在每个数字上重复 start end .

    我在谷歌上搜索了答案,似乎是 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.\nGo to the store and buy some more, 99 bottles of beer on the wall.\n".to_string(),
            1 => "1 bottle of beer on the wall, 1 bottle of beer.\nTake it down and pass it around, no more bottles of beer on the wall.\n".to_string(),
            2 => "2 bottles of beer on the wall, 2 bottles of beer.\nTake one down and pass it around, 1 bottle of beer on the wall.\n".to_string(),
            num => format!("{0} bottles of beer on the wall, {0} bottles of beer.\nTake one down and pass it around, {1} bottles of beer on the wall.\n",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.\nTake one down and pass it around, 7 bottles of beer on the wall.\n\n7 bottles of beer on the wall, 7 bottles of beer.\nTake one down and pass it around, 6 bottles of beer on the wall.\n\n6 bottles of beer on the wall, 6 bottles of beer.\nTake one down and pass it around, 5 bottles of beer on the wall.\n");
    }
    

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

    0 回复  |  直到 6 年前
        1
  •  7
  •   Shepmaster Tim Diekmann    6 年前

    您的问题与字符串连接无关。这与以下事实有关 8..6 是一个空迭代器,因为范围只向前迭代。因为 8 >= 6 ,迭代器产生 None 第一次打电话给 next .

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

    这可以通过交换来固定。 start end 呼唤 rev() 向后迭代。

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

    不过,还有一个问题。在一定范围内 start..end , 开始 包括但 结束 是独一无二的。例如,上面的代码打印 7 6 ; 8 未打印。见 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))
    }
    

    注意:您的测试仍然失败,因为它期望每节之间有两个新行,但您的代码只生成一个新行。我把这事交给你处理。γ射线