我尝试使用&str
代替String
,但这有编译错误。我最终得到了:
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);
}
答案 0 :(得分:5)
有两件事可以立即帮助缩短这个计划:
&str
:在to_string
这里打电话太多了我会把它写成:
fn main() {
let words = vec!["apple", "orange", "banana"];
let word = match words.get(4) {
Some(&s) => s,
None => "nil"
};
println!("word: {}", word);
}
请注意,Vec<T>::get
会返回Option<&T>
,因此我们需要Option<&&str>
,因为我们希望s
属于&str
类型(单&
}),我们使用Some(&s)
作为模式。另一个选项是Some(s) => *s,
(此处,s
为&&str
并取消引用它。)
当然,通过查看Option
的特定API,可以进一步减少这一点。虽然不那么普遍,但是Option
和Result
经常用在Rust中(因此它们在前奏中很多!!!)因此值得学习它们的API。
在这种情况下,unwrap_or
将提供Option
内的值或传递给它的值:
fn main() {
let words = vec!["apple", "orange", "banana"];
let word = *words.get(4).unwrap_or(&"nil");
println!("word: {}", word);
}
参考杂志以排列类型(也就是俄罗斯方块类型)并且一切都很好。
答案 1 :(得分:2)
在&str
和String
之间做出决定时,务必记住strings的强制规则。
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);
}
如果长度仍然是您关注的话,您可以合并words
和word
匹配代码,但我认为这(可能包括类型注释)最简洁而不会影响清晰度。
答案 2 :(得分:2)
我不确定,你想要实现什么,但这可能是你完成你的代码所做的最好的方式:
fn main() {
let words = vec!["apple", "orange", "banana"];
let word = words.get(4).cloned().unwrap_or("nil").to_string();
println!("word: {}", word);
}
棘手的部分是cloned()
:get()
方法将返回对向量内部值的可选引用。但由于向量已经存在引用,我们最终得到Option<&&str>
(两个引用)。 cloned()
调用删除了一个引用,因此我们有Option<&str>
。
另请注意,在此示例中,最后的to_string()
调用不是必需的 - 我们只能使用&str
执行所有操作。