In Python, this would be final_char = mystring[-1]
. How can I do the same in Rust?
I have tried
mystring[mystring.len() - 1]
but I get the error the type 'str' cannot be indexed by 'usize'
In Python, this would be final_char = mystring[-1]
. How can I do the same in Rust?
I have tried
mystring[mystring.len() - 1]
but I get the error the type 'str' cannot be indexed by 'usize'
That is how you get the last char
(which may not be what you think of as a "character"):
mystring.chars().last().unwrap();
Use unwrap
only if you are sure that there is at least one char in your string.
Warning: About the general case (do the same thing as mystring[-n]
in Python): UTF-8 strings are not to be used through indexing, because indexing is not a O(1) operation (a string in Rust is not an array). Please read this for more information.
However, if you want to index from the end like in Python, you must do this in Rust:
mystring.chars().rev().nth(n - 1) // Python: mystring[-n]
and check if there is such a character.
If you miss the simplicity of Python syntax, you can write your own extension:
trait StrExt {
fn from_end(&self, n: usize) -> char;
}
impl<'a> StrExt for &'a str {
fn from_end(&self, n: usize) -> char {
self.chars().rev().nth(n).expect("Index out of range in 'from_end'")
}
}
fn main() {
println!("{}", "foobar".from_end(2)) // prints 'b'
}
mystring.chars().last().unwrap()
looks easier to read, and is more concise. Is there a way to use it without unwrap?
. I had the impression that using unwrap
was discouraged. –
Hallux unwrap
was discouraged" It's a matter of whether to panic!
or not to panic!
. unwrap
is to express that any potential error coming from there is irrecoverable and should not happen. There still are legitimate cases for this. –
Joiner expect
. –
Comportment unwrap
with expect
above. The latter can often be better, but it's also noise if the only message you can think of is "IT SHOULD WORK!!!1". –
Joiner One option is to use slices. Here's an example:
let len = my_str.len();
let final_str = &my_str[len-1..];
This returns a string slice from position len-1
through the end of the string. That is to say, the last byte of your string. If your string consists of only ASCII values, then you'll get the final character of your string.
The reason why this only works with ASCII values is because they only ever require one byte of storage. Anything else, and Rust is likely to panic at runtime. This is what happens when you try to slice out one byte from a 2-byte character.
For a more detailed explanation, please see the strings section of the Rust book.
As @Boiethios mentioned
let last_ch = mystring.chars().last().unwrap();
Or
let last_ch = codes.chars().rev().nth(0).unwrap();
I would rather have (how hard is that!?)
let last_ch = codes.chars(-1); // Not implemented as rustc 1.56.1
The optimal way is .chars().next_back()
.
The .chars().last()
would consume the whole string, so has linear complexity.
There is another method, depending on context. If you just want to assess what the last character of a string is, you can simply use the ends_with method. For example, say I would like to remove '/', if this is the last character of a user-inputted String path. Then, I can simply do:
if path.ends_with('/') {
path.pop();
}
.pop()
is a good addition I say. It fits the title just with the side-effect of also removing it from the String
. Some may be interested in that. –
Njord © 2022 - 2024 — McMap. All rights reserved.
abcd
as my string, I would want to getd
as the final char. My current use case did not involve the use of strings likeあいうえお
, but if so, then I would have liked to get the final charお
. – Halluxcafé
isé
or´
. If it should beé
, you want to iterate by graphemes instead ofchar
s. – Alonsoalonzocafé
to beé
. You mentioned graphemes, and I did some googling to check it out (for potential future use cases). Looks like I may have to import an external crate to do so as mentioned here: users.rust-lang.org/t/… – Halluxunicode-segmentation
crate) is actually better in this regard. If you copy and paste"café"[-1]
into your Python interpreter, it probably won't give you"é"
. – Alonsoalonzo"é"
, I got'́'
, whatever that is. – Hallux