Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

FizzBuzz Function in Rust

This is my code:

fn main() { 
  fn fizz_buzz<'a>(i: i32) -> &'a str { 

    if i % 15 == 0 { 
        "FizzBuzz"
    } else if i % 5 == 0 { 
        "Buzz"
    } else if i % 3 == 0 { 
        "Fizz"
    } else { 
        &i.to_string()
    }
  }

  for i in 1..101 { 
    println!("{}" , fizz_buzz(i));
  }
}

The compiler gives me this error:

error[E0515]: cannot return reference to temporary value
  --> src/main.rs:11:9
   |
11 |         &i.to_string()
   |         ^-------------
   |         ||
   |         |temporary value created here
   |         returns a reference to data owned by the current function

For more information about this error, try `rustc --explain E0515`.
error: could not compile `playground` due to previous error

I tried a static lifetime.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Your function will correctly give back a reference to the strings "FizzBuzz," "Buzz," and "Fizz" (whose lifetimes are static since they’re compiled in) however the &i.to_string() does not have that same property. Let’s look at the lifetime in detail:

When fizz_buzz is called, i is copied (because i32 implements the Copy trait) and given to it. In that else block, however, we do the following:

  1. Create a new String whose lifetime cannot exceed the lifetime of i
  2. Return a reference to that String

however, the lifetime of i is only as long as the fizz_buzz function call! Since we need to use it outside of that scope, Rust calls foul.

There are a couple ways to make this type safe. You could return owned values rather than references:

fn fizz_buzz(i: i32) -> String {
    if i % 15 == 0 { String::from("FizzBuzz") }
    else if i % 5 == 0 { String::from("Buzz") }
    else if i % 3 == 0 { String::from("Fizz") }
    else { i.to_string() }
}

Though this will end up creating a lot of identical objects on the heap (consider how many "Fizz"es there are, for instance)

The other option that I’d prefer is to have fizz_buzz return an Option<&str>, and have the calling scope handle the case when fizz_buzz gives None.

fn fizz_buzz(i: i32) -> Option<&'static str> {
    if i % 15 == 0 { Some("FizzBuzz") }
    else if i % 5 == 0 { Some("Buzz") }
    else if i % 3 == 0 { Some("Fizz") }
    else { None }
}

for i in 1..101 {
    match fizz_buzz(i) {
        Some(v) => println!("{}", v),
        None => println!("{}", i),
    }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading