1

I'm working through the codewars katas, and came upon this problem:

fn divisors(num: i32) -> Result<Vec<i32>, &'static str> {
    let mut d: Vec<i32> = Vec::new();

    for n in 2..=(num / 2) + 1 {
        if num % n == 0 {
            d.push(n)
        }
    }

    match d {
        v if v.is_empty() => Err(format!("{} is prime!", num).as_str()),
        _ => Ok(d),
    }
}

When I try to compile this I get the following error:

error[E0515]: cannot return value referencing temporary value
  --> src/lib.rs:11:30
   |
11 |         v if v.is_empty() => Err(format!("{} is prime!", num).as_str()),
   |                              ^^^^----------------------------^^^^^^^^^^
   |                              |   |
   |                              |   temporary value created here
   |                              returns a value referencing data owned by the current function
   |
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

I get that this means I'm trying to return a reference to a slice of a String which no longer exists - because it's been destroyed, but how can I overcome this?

I want to return a Result whose Err value is a &str. Is that even a reasonable thing to do? At least I think that's what I want to do because of the following line in the instructions:

divisors(13); // should return Err("13 is prime")
trent
  • 25,033
  • 7
  • 51
  • 90
Salim Fadhley
  • 6,975
  • 14
  • 46
  • 83
  • 1
    return the string ? https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=374360a90e7a1e885796084920d5602a – Stargateur Mar 28 '20 at 20:03
  • Or better https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=e74d1bb8202b9440a801f66ea1f071df – Stargateur Mar 28 '20 at 20:12
  • I'm trying to return a Result object of the type `Result, &'static str>`. Returning a string won't do, I want to return a Result whose error object contains a sting. – Salim Fadhley Mar 28 '20 at 20:30
  • I see what you did there - you changed the return type to `Result, DivisorsError>`. Is it not possible to return a Err whose value is a string slice? – Salim Fadhley Mar 28 '20 at 20:32
  • @Stargateur, it's really easy to return `Err('number is not a prime')` but what if I wanted to return an Err with some custom text instead of the constant string? Can it be done? – Salim Fadhley Mar 28 '20 at 20:34
  • 2
    think to what you ask you want to return a dynamic static str. What you ask don't make sense, if you want to return a **formated** string you need dynamic allocation, you already do it with format, it's return a String. Either you return "The number is prime" so a static str either you return a String either something else. – Stargateur Mar 28 '20 at 20:34
  • I think this is fundamentally the same as [Return local String as a slice (&str)](https://stackoverflow.com/questions/29428227/return-local-string-as-a-slice-str). Wrapping the string in a `Result` doesn't change the fundamental reality: you can't return local things by reference; just return the whole thing. – trent Mar 28 '20 at 20:39
  • Thanks @Stargateur. Could this be a bug in the question? https://www.codewars.com/kata/544aed4c4a30184e960010f4/rust The question implies that the value of the Err will be &str but also dynamically generated. – Salim Fadhley Mar 28 '20 at 20:41
  • 2
    The kata does say "use [...] `Result, String>` in Rust". – trent Mar 28 '20 at 20:42
  • Yes, I misread the question. Thank you all. – Salim Fadhley Mar 29 '20 at 20:31

0 Answers0