0

I wrote the following code:

const DIGIT_SPELLING: [&str; 10] = [
    "", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"
];

fn to_spelling_1(d: u8) -> &str {
    DIGIT_SPELLING[d as usize]
}

fn main() {
    let d = 1;
    let s = to_spelling_1(d);
    println!("{}", s);
}

This gives the following compiler error:

error[E0106]: missing lifetime specifier
 --> src/main.rs:5:28
  |
5 | fn to_spelling_1(d: u8) -> &str {
  |                            ^ expected lifetime parameter
  |
  = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
  = help: consider giving it an explicit bounded or 'static lifetime

To fix the problem, I changed my code to this:

const DIGIT_SPELLING: [&str; 10] = [
    "", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"
];

fn to_spelling_1<'a>(d: u8) -> &'a str { // !!!!! Added the lifetime. !!!!!
    DIGIT_SPELLING[d as usize]
}

fn main() {
    let d = 1;
    let s = to_spelling_1(d);
    println!("{}", s);
}

This code compiles and runs without error. Why did I need to add the 'a lifetime? Why does adding the 'a lifetime fix the error?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
vamsikal
  • 51
  • 1
  • 6
  • 1
    Extremely relevant: https://stackoverflow.com/q/31609137/1233251 (it answers _at least_ the first part of the question). Consider also reading the section of the book on [lifetimes](https://doc.rust-lang.org/stable/book/second-edition/ch10-03-lifetime-syntax.html). – E_net4 Mar 27 '18 at 09:50
  • Thanks for the references! – vamsikal Mar 27 '18 at 10:03

1 Answers1

2

Any function that returns a reference must include a lifetime for this reference. If the function also takes at least one by-reference parameter then lifetime elision means that you can omit the return lifetime, but elision does not occur if there is no by-reference parameter, like in your example.

Note that in your case, it would make more sense to use an explicit 'static lifetime rather than a generic since the value you return is always 'static:

fn to_spelling_1(d: u8) -> &'static str {
    DIGIT_SPELLING[d as usize]
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Jmb
  • 18,893
  • 2
  • 28
  • 55
  • Thank you very much for the answer. I did use 'static and that worked. But I wanted to understand how the generic lifetime parameters worked. – vamsikal Mar 27 '18 at 10:04