Reputation: 555
I want to split a string by a separator only once and put it into a tuple. I tried doing
fn splitOnce(in_string: &str) -> (&str, &str) {
let mut splitter = in_string.split(':');
let first = splitter.next().unwrap();
let second = splitter.fold("".to_string(), |a, b| a + b);
(first, &second)
}
but I keep getting told that second
does not live long enough. I guess it's saying that because splitter
only exists inside the function block but I'm not really sure how to address that. How to I coerce second
into existing beyond the function block? Or is there a better way to split a string only once?
Upvotes: 17
Views: 17226
Reputation: 6949
str::split_once
is now built-in.
Doc examples:
assert_eq!("cfg".split_once('='), None);
assert_eq!("cfg=".split_once('='), Some(("cfg", "")));
assert_eq!("cfg=foo".split_once('='), Some(("cfg", "foo")));
assert_eq!("cfg=foo=bar".split_once('='), Some(("cfg", "foo=bar")));
Upvotes: 12
Reputation: 430270
You are looking for str::splitn
:
fn split_once(in_string: &str) -> (&str, &str) {
let mut splitter = in_string.splitn(2, ':');
let first = splitter.next().unwrap();
let second = splitter.next().unwrap();
(first, second)
}
fn main() {
let (a, b) = split_once("hello:world:earth");
println!("{} --- {}", a, b)
}
Note that Rust uses snake_case
.
I guess it's saying that because splitter only exists inside the function block
Nope, it's because you've created a String
and are trying to return a reference to it; you cannot do that. second
is what doesn't live long enough.
How to I coerce
second
into existing beyond the function block?
You don't. This is a fundamental aspect of Rust. If something needs to live for a certain mount of time, you just have to make it exist for that long. In this case, as in the linked question, you'd return the String
:
fn split_once(in_string: &str) -> (&str, String) {
let mut splitter = in_string.split(':');
let first = splitter.next().unwrap();
let second = splitter.fold("".to_string(), |a, b| a + b);
(first, second)
}
Upvotes: 25