Unpack a splitn into a tuple in Rust? [duplicate]
Asked Answered
B

1

17

I want to do the following in Rust:

let (command, options) = message.splitn(2, ' ');

This can't be done because of:

expected struct `std::str::SplitN`, found tuple

The split will always be two and I like having named variables. The message may not contain a space character.

Bunny answered 8/6, 2020 at 7:39 Comment(0)
C
25

The splitn() method returns an iterator over the parts, so the only way to access them is to actually iterate over them. If you know that there always will be two parts, you can do this:

let mut iter = message.splitn(2, ' ');
let command = iter.next().unwrap();
let options = iter.next().unwrap();

This will work fine as long as message contains at least one space character. For a message without a space, this will panic on the last line, since the iterator is already terminated, so you would call unwrap() on None. (Note that you need 2 as the first argument to splitn() if you want to get two items.)

Starting from Rust 1.52, you can use the split_once() method:

if let Some((command, options)) = message.split_once(' ') {
    // handle command, options
} else {
    // handle error
}

As pointed out in the comments, another option is to use str::split_at() together with str::find():

let (command, options) = message.split_at(message.find(' ').unwrap());

Note that the space character will be included in options with this solution, whereas the other approaches don't include it.

Corinacorine answered 8/6, 2020 at 7:47 Comment(4)
I think str::split_at with Iterator::position might also be handyMagritte
@Magritte Nice idea! You would need to use str::find() instead of Iterator::position, since you need the byte offset rather than the character index, but I'll add it to the answer.Corinacorine
Since Rust 1.52 there is str::split_once, which returns an Option of a tuple.Danella
@JannisFroese Thanks, I included this in the answer.Corinacorine

© 2022 - 2024 — McMap. All rights reserved.