3

I am trying to parse an environment value; using std::env as follows

let environment = env::var("SENSIBULL_ENVIRONMENT").unwrap();

This returns a string to the variable environment. If I want to pass a default value, then I have to use the below code

let environment = env::var("SENSIBULL_ENVIRONMENT").unwrap_or("development".into());

but I was expecting to do it like

let environment = env::var("SENSIBULL_ENVIRONMENT").unwrap_or("development");

as mentioned in the Rust example

But then it shows error String expected but found &str

Why is that error not happening in the example code?

Asnim P Ansari
  • 1,932
  • 1
  • 18
  • 41
  • Does this answer your question? [What are the differences between Rust's \`String\` and \`str\`?](https://stackoverflow.com/questions/24158114/what-are-the-differences-between-rusts-string-and-str) – springworks00 Apr 23 '20 at 17:51
  • 1
    It's better to use `.unwrap_or_else(|| "development".into())`, so the default string isn't allocated if the environment variable is present. – Aloso Apr 23 '20 at 17:55

1 Answers1

5

In Rust, string literals are of type &str, and environment variables are of type String. Essentially, &strs have a fixed size, while Strings can be dynamically changed and resized (read more here). unwrap_or requires that the alternate value be of the same type as the option value, which means that you must provide a String to match the type of the environment variable. That's why you have to call .into to convert it to a string. In their example, the option uses a string literal, which is also of type &str, so there are no errors.

trent
  • 25,033
  • 7
  • 51
  • 90
Aplet123
  • 33,825
  • 1
  • 29
  • 55
  • "In Rust, string literals are of type &str, and environment variables are of type String. " complement: envvars are `String` because the unix `getenv` is super unsafe, it returns a pointer into the "environment data" buffer so the pointer can be invalidated at essentially any point. Therefore Rust immediately copies that data into an owned buffer (an `OsString`), and optionally decodes it to a "proper" String for convenience (`env::var_os` provides access to the "raw" data even if it's not valid unicode). – Masklinn Apr 24 '20 at 07:33