Reputation: 5154
I've tried using &str
instead of String
, but that has compilation errors. I ended up with:
fn main()
{
let words: Vec<String> = vec!["apple".to_string(), "orange".to_string(), "banana".to_string()];
let word: String = match words.get(4)
{
Some(s) => s.to_string()
, None => "nil".to_string()
};
println!("word: {}", word);
}
Upvotes: 1
Views: 1442
Reputation: 3207
It is important to remember the coercion rules of strings when deciding between &str
and String
.
fn main()
{
let words = vec!["apple", "orange", "banana"]; // Vec<&str>
let word = match words.get(2) { // &str
Some(&s) => s
None => "nil"
};
println!("word: {}", word);
}
You could consolidate the words
and word
matching code if length was still a concern for you, but I think this (perhaps including type annotations) is the most succinct without compromising clarity.
Upvotes: 2
Reputation: 299930
There are two things that will immediately help shorten this program:
&str
: way too many calls to to_string
hereI would write it as:
fn main() {
let words = vec!["apple", "orange", "banana"];
let word = match words.get(4) {
Some(&s) => s,
None => "nil"
};
println!("word: {}", word);
}
Note that Vec<T>::get
returns an Option<&T>
, thus here an Option<&&str>
, since we want s
to be of type &str
(single &
), we use Some(&s)
as the pattern. Another option would be Some(s) => *s,
(here, having s
be &&str
and dereferencing it).
Of course, this can all be further reduced by looking at the specific API of Option
. Somewhat less universal, but Option
and Result
are very often used in Rust (so much they are in the prelude!!!) and therefore it's worth learning their APIs.
In this case unwrap_or
will provide either the value inside Option
or the value passed to it:
fn main() {
let words = vec!["apple", "orange", "banana"];
let word = *words.get(4).unwrap_or(&"nil");
println!("word: {}", word);
}
Bit of reference juggling to line-up the types (aka type Tetris) and it's all good.
Upvotes: 7
Reputation: 88736
I'm not exactly sure, what you want to achieve, but this is probably the best way to do exactly what you did in your code:
fn main() {
let words = vec!["apple", "orange", "banana"];
let word = words.get(4).cloned().unwrap_or("nil").to_string();
println!("word: {}", word);
}
The tricky part is cloned()
: the get()
method will return an optional reference to the value inside of the vector. But since the vector already holds references, we end up with Option<&&str>
(two references). The cloned()
call removes one reference, thus we have Option<&str>
.
Also note that in this example the final to_string()
call isn't necessary -- we can do everything only with &str
.
Upvotes: 3