1

I'm having trouble unwrapping Options and converting the values to string slices.

  • When the Option has Some value, I want to convert it to a &str.
  • When the Option is None, I simply return an empty string slice "".

For example:

let val: Option<u8> = row.get(k);
match val {
    None => "",
    Some(v) => v.to_string().as_str()
}

But this fails with errors like this.

temporary value dropped while borrowed
consider using a `let` binding to create a longer lived value rustc E0716
main.rs(.....): temporary value is freed at the end of this statement

I have tried breaking it down in various different ways, for example like this

let val: Option<u8> = row.get(k);
match val {
    None => "",
    Some(v) => {
        let vstr = v.to_string();
        vstr.as_str()
    }
}

But I'm still really stuck. I've looked through a many similar problems but none are quite the same, and I'm still stuck. How can I do this?

Clarification, I want the decimal representation of the tinyint, not the character point. This is not utf8 string, just a number.

let x: u8 = 10;
let s: String = x.to_string();
println!("10 = {}", s);

This should print 10 = 10

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • u8 is a single byte, shouldnt it be [u8] ? – Antonin GAVREL Apr 26 '21 at 01:15
  • Or, is it really `Option` and maybe you want to convert that 8 bit integer into it's decimal representation in a string? – harmic Apr 26 '21 at 01:30
  • @antoninGRAVIL, no not really meant to be a byte char. think of it as a tinyint, harmic, yes more like a decimal representation in a string is what I want. – Christopher Plewright Apr 26 '21 at 01:41
  • it's because you are borrowing from `vstr` which is dropped when it goes out of scope. Since you are returning a reference, that reference must point to something that outlives the reference. Try returning a `String` instead of an `&str`. – Mel Apr 26 '21 at 01:55
  • @Mel YES! by using String I'm able to work around it for now. – Christopher Plewright Apr 26 '21 at 02:15
  • Does this answer your question? [Proper way to return a new string in Rust](https://stackoverflow.com/questions/43079077/proper-way-to-return-a-new-string-in-rust) – Jmb Apr 26 '21 at 06:32
  • @Jmb, I'd say that link only indirectly helps, because it adds to my understanding of the underlying concepts, ie; lifetime and ownership. I'm not returning a string. Thanks for sharing it. – Christopher Plewright Apr 27 '21 at 08:50

2 Answers2

3

If you're trying to use the &str in the same function, you can hoist the declaration so that the string lives long enough:

let val: Option<u8> = row.get();
let vstr;
let msg = match val {
    None => "",
    Some(v) => {
        vstr = v.to_string();
        vstr.as_str()
    }
};
println!("value is {}", msg);

If your goal is to return the &str to a caller, then that's not possible. That's a borrowed value, and the string that owns the memory won't live past the end of the function at most. You can either return String or Cow<'static, str>.

For example, you could do this:

let val: Option<u8> = row.get();
match val {
    None => "".to_owned(),
    Some(v) => v.to_string(),
}

or this:

let val: Option<u8> = row.get();
match val {
    None => "".into(),
    Some(v) => v.to_string().into(),
}
bk2204
  • 64,793
  • 6
  • 84
  • 100
0

In the more general case, when you cannot keep the string around, you could use Cow:

let val: Option<u8> = row.get(k);
let msg = match val {
    None => Cow::Borrowed(""),
    Some(v) => Cow::Owned(v.to_string()),
};

Now msg holds either a borrowed or an owned string, depending on the situation.

user4815162342
  • 141,790
  • 18
  • 296
  • 355