2

The following is obviously not working:

fn main() {
    for i in range(1i, 101) {
        println!("{}", if i % 15 == 0 {
            "Fizzbuzz"
        } else if i % 5 == 0 {
            "Buzz"
        } else if i % 3 == 0 {
            "Fizz"
        } else {
            i
        });
    };
}

It can be made work like this:

fn main() {
    for i in range(1i, 101) {
       println!("{}", if i % 15 == 0 {
            "Fizzbuzz".to_string()
        } else if i % 5 == 0 {
            "Buzz".to_string()
        } else if i % 3 == 0 {
            "Fizz".to_string()
        } else {
            i.to_string()
        });
    }
}

But what is the most elegant (probably idiomatic) way to make it work in a similar fashion using if/else with expressions?

OderWat
  • 5,379
  • 3
  • 29
  • 31
  • What do you mean "using implicit returns"? There are no **explicit returns** in your example code. – Shepmaster Dec 29 '14 at 17:43
  • This has a [comprehensive exploration of FizzBuzz](http://chrismorgan.info/blog/rust-fizzbuzz.html) for Rust. – Shepmaster Dec 29 '14 at 17:44
  • Yeah sorry, wrong term. I meant using the condition as expression to "return" the result as a value. And than you for the link! – OderWat Dec 29 '14 at 20:02

1 Answers1

5

The comprehensive exploration of FizzBuzz uses a now deprecated struct called MaybeOwned. Here's the updated version, with the delightfully-named CowString:

use std::borrow::Cow;

fn main() {
    for i in 1..10 {
        println!("{}", if i % 15 == 0 {
            Cow::Borrowed("Fizzbuzz")
        } else if i % 5 == 0 {
            Cow::Borrowed("Buzz")
        } else if i % 3 == 0 {
            Cow::Borrowed("Fizz")
        } else {
            Cow::Owned(i.to_string())
        });
    };
}

However, you should read that full blog post for maximal education!

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • CowString() seriously? I will try to find the discussion that made this possible. It is even marked stable! Fair enough :) The blog post helps a lot! – OderWat Dec 29 '14 at 20:26
  • It's a silly artifact of a few things: Rust style is to have `InitialCaps` for structs and traits, acronyms should obey this as well, and it stands for Copy On Write. Thus we end up with `Cow` ^_^ – Shepmaster Dec 29 '14 at 20:28
  • 2
    I’ve been wondering when I should update the article to master rather than 0.12. I should probably add a note at the least. – Chris Morgan Dec 30 '14 at 02:16
  • 1
    @Shepmaster: actually it’s *clone* on write, not *copy* on write. – Chris Morgan Dec 30 '14 at 05:01
  • @ChrisMorgan I suppose that's a very important detail in a language that treats those differently! – Shepmaster Dec 30 '14 at 05:03
  • Well... as of today `into_cow()` does not work anymore and I have a hard time to find how it is done now? – OderWat Jan 03 '15 at 17:07
  • @OderWat sounds like you should open a new question with the code that doesn't work and the error message(s) you get. – Shepmaster Jan 03 '15 at 17:16
  • @Shepmaster Well. It stays the same question but the preferred answer now does not work anymore. – OderWat Jan 03 '15 at 17:23
  • @OderWat fixed the example. To reiterate though, this is probably not the FizzBuzz solution you want. The solution with the defined `enum` is a lot better, IMO. – Shepmaster Jan 03 '15 at 18:45
  • @Shepmaster Thank you for fixing. Actually there is no solution of what I really asked for. It would need to create a &str out of thin air. I like the version with "let x/as_slice()" the best. I am not sure how much overhead the "into_cow()" will create in comparison. To create a function I would generally simply go with the to_string() variant. The enum solution delays everything to the fmt::Show implementation. That is nice but the furthest away of my original question where fizzbuzz was just an example of. – OderWat Jan 03 '15 at 20:02