I'm attempting to create pub fn sing(start: i32, end: i32) -> String
that returns a concatenated string of the results of calling pub fn verse(num: i32) -> String
repeatedly on each number between start
and end
.
I've googled for the answer and it seems that Rust String concatenation answers my question, and if I even write my code in playground it works, but:
my code:
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))
}
The problem is that
#[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");
}
fails with beer::sing(8,6)
returning ""
.
Your problem has nothing to do with string concatenation. It has to do with the fact that
8..6
is an empty iterator, because a range only iterates forwards. Because8 >= 6
, the iterator yieldsNone
on the first call tonext
.This can be fixed by swapping
start
andend
and callingrev()
to iterate backwards.However, there's still another problem. In a range
start..end
,start
is inclusive butend
is exclusive. For example, the code above prints7
and6
;8
is not printed. See How do I include the end value in a range?Putting it all together,
sing
should look like:Note: Your test still fails because it expects two newlines between each verse, but your code only generates one. I'll leave this up to you to fix.