我试图弄清楚如何在 Rust 中匹配 String
。
我最初尝试像这样匹配,但我发现 Rust 不能从 std::string::String
隐式转换为 &str
。
fn main() {
let stringthing = String::from("c");
match stringthing {
"a" => println!("0"),
"b" => println!("1"),
"c" => println!("2"),
}
}
这有错误:
error[E0308]: mismatched types
--> src/main.rs:4:9
|
4 | "a" => println!("0"),
| ^^^ expected struct `std::string::String`, found reference
|
= note: expected type `std::string::String`
found type `&'static str`
然后我尝试构造新的 String
对象,因为我找不到将 String
转换为 &str
的函数。
fn main() {
let stringthing = String::from("c");
match stringthing {
String::from("a") => println!("0"),
String::from("b") => println!("1"),
String::from("c") => println!("2"),
}
}
这给了我3次以下错误:
error[E0164]: `String::from` does not name a tuple variant or a tuple struct
--> src/main.rs:4:9
|
4 | String::from("a") => return 0,
| ^^^^^^^^^^^^^^^^^ not a tuple variant or struct
如何在 Rust 中实际匹配 String
?
stringthing.as_str()
可能是所有答案中最直接的;我不喜欢 as_ref
,因为它过于笼统,可能导致错误,而且不那么明确,as_ref()
将成为 &str
并不完全清楚,as_str
简单明了.
as_str
尚不存在时,答案被接受。我改变了接受的答案,但感谢所有回答这个问题的人!
更新: 像这样使用 .as_str()
将 String
转换为 &str
:
match stringthing.as_str() {
"a" => println!("0"),
"b" => println!("1"),
"c" => println!("2"),
_ => println!("something else!"),
}
原因 .as_str()
更简洁并强制执行更严格的类型检查。特征 as_ref
是为多种类型实现的,并且它的行为可能会针对类型 String
进行更改,从而导致意外结果。同样,如果输入参数改变类型,当该类型实现特征 as_ref
时编译器不会发出问题信号。
文档建议使用 as_str
以及 https://doc.rust-lang.org/std/string/struct.String.html、https://doc.rust-lang.org/std/primitive.str.html
老答案:
as_slice
已弃用,您现在应该改用特征 std::convert::AsRef
:
match stringthing.as_ref() {
"a" => println!("0"),
"b" => println!("1"),
"c" => println!("2"),
_ => println!("something else!"),
}
请注意,您还必须明确处理包罗万象的情况。
你可以这样做:
match &stringthing[..] {
"a" => println!("0"),
"b" => println!("1"),
"c" => println!("2"),
_ => println!("something else!"),
}
从 Rust 1.7.0 开始,还有一个 as_str
方法:
match stringthing.as_str() {
"a" => println!("0"),
"b" => println!("1"),
"c" => println!("2"),
_ => println!("something else!"),
}
你也可以做
match &stringthing as &str {
"a" => println!("0"),
"b" => println!("1"),
"c" => println!("2"),
_ => println!("something else!"),
}
看:
标准::字符串::字符串
std::ops::Deref
解除强制
.as_str()
相同,而且更短。
编者注:此答案适用于 Rust 1.0 之前的版本,不适用于 Rust 1.0
您可以匹配字符串切片。
match stringthing.as_slice() {
"a" => println!("0"),
"b" => println!("1"),
"c" => println!("2"),
_ => println!("something else!"),
}
.as_ref()
或 .as_str()
,两者都没有取得所有权。
你可以试试:
fn main() {
let stringthing = String::from("c");
match &*stringthing {
"a" => println!("0"),
"b" => println!("1"),
"c" => println!("2"),
_ => println!("else")
}
}
&*stringthing
的含义和作用,它可能会提高您的答案的实用性。
您可以通过执行以下操作将 String
转换为 &str
:
fn main() {
let stringthing = String::from("c");
match &stringthing[..] {
"a" => println!("0"),
"b" => println!("1"),
"c" => println!("2"),
}
}
在字符串上使用 as_str() 来获取字符串切片
fn main() {
let stringthing = String::from("c");
match stringthing.as_str() {
String::from("a") => println!("0"),
String::from("b") => println!("1"),
String::from("c") => println!("2"),
}
}
如果您从控制台获取输入并希望对其执行匹配,请务必在 as_str() 之后调用 trim() 以从输入中删除转义字符,即 '\n'。如在
match stringthing.as_str().trim() {...}
trim()
功能。仅使用as_ref()
与字符串不匹配。trim()
删除了空格。这对于匹配用户输入非常有用。read_line
读取一行。行以\n
结束。.trim_end()
(或更准确地说,trim_end_matches('\n')
)将为您删除它。