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();
Answer from rodrigo on Stack Overflowtrying to trim and lowercase my String in rust - Stack Overflow
Performance issue: can I avoid of using the slow to_lowercase function?
Add `as_lowercase` et. al - libs - Rust Internals
Char to_lowercase problem
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();
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.
I'm trying to implement a simple fuzzy sort library in rust, which I've already wrote a version in JavaScript and I would like to see whether Rust will give a better performance to do that.
Most code's performance showed the power of Rust, but the str::to_lowercase slow down the whole program.
I use the to_lowercase function to case insensitively compare the chars of string. I know using the eq_ignore_ascii_case function will be faster but I still want to consider the non-ASCII characters cases.
So is there any way to get the goal with a better performance? I've tried convert characters into lowercase in the iterator, but the char::to_lowercase return ToLowercase and can not be compared directly.
Below is a bench of str::to_lowercase, did I do anything wrong?
#[bench]
fn lowercase(b: &mut test::Bencher) {
let target = String::from("Search some long string to test the lowercase benchmark.");
b.iter(|| target.to_lowercase());
}If you use the std::string::String type instead of &str, there is a less verbose way with the additional benefit of Unicode support:
fn main() {
let test_str = "รผbercode"; // type &str
let uppercase_test_string = test_str.to_uppercase(); // type String
let uppercase_test_str = uppercase_test_string.as_str(); // back to type &str
println!{"{}", test_str};
println!{"{}", uppercase_test_string};
println!{"{}", uppercase_test_str};
}
I think the recommended way is to use String::to_ascii_uppercase:
fn main() {
let r = "smash".to_ascii_uppercase();
println!("Hulk {}!", r); // Hulk SMASH!
//or one liner
println!("Hulk {}!", "smash".to_ascii_uppercase());
}