Rust 中的匹配字符串
Matching string in Rust
我是 Rust (1.31) 的新手,我想了解一段无法编译的简单代码:
fn main() {
s = String::from("foo");
match s {
"foo" => {
println!("Yes");
}
_ => {
println!("No");
}
}
}
相关的错误是:
10 | "foo" => {
| ^^^^^ expected struct `std::string::String`, found reference
出现这个错误后,我决定将代码更改为:
fn main() {
let s = String::from("foo");
match s {
String::from("foo") => {
println!("Yes");
}
_ => {
println!("No");
}
}
}
这样做,我希望得到正确的类型,但事实并非如此:
10 | String::from("foo") => {
| ^^^^^^^^^^^^^^^^^^^ not a tuple variant or struct
我对编译器的这条消息感到很困惑,最后我设法通过实现使其工作:
fn main() {
let s = String::from("foo");
match &s as &str {
"foo" => {
println!("Yes");
}
_ => {
println!("No");
}
}
}
但是,我不理解使该解决方案成为正确解决方案的潜在机制以及为什么我的第二个示例不起作用。
第一个示例不起作用,因为 s
是类型 String
,它是一个字符串变体,它拥有其中的数据。它与字符串文字(可用作类型 &str
)匹配。 match 不明白如何比较这两种不同的类型,所以它会出错。
但是 String
通过实施 Deref<Target=str>
取消对 &str
的引用,这意味着可以在需要 &str
的地方使用对 String
的引用,例如将其与一个进行比较。这就是第三个示例中发生的情况。通过创建引用 &s
,可以发生隐式取消引用,并且两种类型可以比较。
您可以使用从 String
:
创建 &str
的显式方法,用更少的魔法实现同样的事情
fn main() {
let s = String::from("foo");
match s.as_str() {
"foo" => {
println!("Yes");
},
_ => {
println!("No");
}
}
}
第二个例子试图使事物具有可比性,使 String
成为通用类型而不是 &str
。它不起作用,因为 match 需要左侧的模式,而不是创建新结构(并且也在幕后分配)的函数调用。即使它可行(例如通过将 String
创建移动到匹配之外),这种方法也不太理想,因为新的 String
需要内存分配。
我是 Rust (1.31) 的新手,我想了解一段无法编译的简单代码:
fn main() {
s = String::from("foo");
match s {
"foo" => {
println!("Yes");
}
_ => {
println!("No");
}
}
}
相关的错误是:
10 | "foo" => {
| ^^^^^ expected struct `std::string::String`, found reference
出现这个错误后,我决定将代码更改为:
fn main() {
let s = String::from("foo");
match s {
String::from("foo") => {
println!("Yes");
}
_ => {
println!("No");
}
}
}
这样做,我希望得到正确的类型,但事实并非如此:
10 | String::from("foo") => {
| ^^^^^^^^^^^^^^^^^^^ not a tuple variant or struct
我对编译器的这条消息感到很困惑,最后我设法通过实现使其工作:
fn main() {
let s = String::from("foo");
match &s as &str {
"foo" => {
println!("Yes");
}
_ => {
println!("No");
}
}
}
但是,我不理解使该解决方案成为正确解决方案的潜在机制以及为什么我的第二个示例不起作用。
第一个示例不起作用,因为 s
是类型 String
,它是一个字符串变体,它拥有其中的数据。它与字符串文字(可用作类型 &str
)匹配。 match 不明白如何比较这两种不同的类型,所以它会出错。
但是 String
通过实施 Deref<Target=str>
取消对 &str
的引用,这意味着可以在需要 &str
的地方使用对 String
的引用,例如将其与一个进行比较。这就是第三个示例中发生的情况。通过创建引用 &s
,可以发生隐式取消引用,并且两种类型可以比较。
您可以使用从 String
:
&str
的显式方法,用更少的魔法实现同样的事情
fn main() {
let s = String::from("foo");
match s.as_str() {
"foo" => {
println!("Yes");
},
_ => {
println!("No");
}
}
}
第二个例子试图使事物具有可比性,使 String
成为通用类型而不是 &str
。它不起作用,因为 match 需要左侧的模式,而不是创建新结构(并且也在幕后分配)的函数调用。即使它可行(例如通过将 String
创建移动到匹配之外),这种方法也不太理想,因为新的 String
需要内存分配。