I'm trying to trim and lowercase my String.
Currently I have
use dialoguer::Input;
let input : String = Input::new()
.with_prompt("Guess a 5 letter word")
.interact_text()
.unwrap();
let guess : &str = input.as_str(); // trim and lowercase
I'm trying to transform String
into a trimmed and lowercased &str
but some functions are only on &str
and others only on String
so I'm having trouble coming up with an elegant solution.
TL;DR: End goal have guess
be a trimmed and lowercase &str
CodePudding user response:
Rust stdlib is not about elegance, but about correctness and efficiency.
In your particular case, trim()
is defined as str::trim(&self) -> &str
because it always returns a substring of the original string, so it does not need to copy or allocate a new string, just compute the begin and end, and do the slice.
But to_lowercase()
is defined as str::to_lowercase(&self) -> String
because it changes each of its characters to the lowercase equivalent, so it must allocate and fill a new String
.
You may thing that if you own the string you can mutate it to lowercase in-place. But that will not work in general because there is not a 1-to-1 map between lowercase and uppercase letters. Think of, for example ß <-> SS
in German.
Naturally, you may know that your string only has ASCII characters... if so you can also use str::make_ascii_lowercase(&mut self)
that does the change in-place, but only for ASCII characters that do have the 1-to-1 map.
So, summing up, the more ergonomic code would be, to trim input
and copy to an owned lowercase:
let guess : String = input.trim().to_lowercase();
Or if you absolutely want to avoid allocating an extra string, but you are positive that only ASCII characters matter:
let mut input = input; //you could also add the mut above
input.make_ascii_lowercase();
let guess: &str = input.trim();
CodePudding user response:
Try this:
let s = " aBcD ";
let s2 = s.trim().to_lowercase();
println!("[{s}], [{s2}]");
The above will work if s
is &str
(as in my example) or String
and it will print:
[ aBcD ], [abcd]
So the last line in your code (if you insist on having guess
as &str
) should become:
let guess: &str = &input.trim().to_lowercase();
Otherwise if you write just:
let guess = input.trim().to_lowercase();
, guess
will be of type String
, as that's what to_lowercase()
returns.