匹配一段 str 或 String
Match a slice of str or String
我有一个函数可以根据切片取 &[&str]
或 &[String]
和 return 不同的值。如果我添加 PartialEq
约束,使用 ==
效果很好:
pub fn info1<'a, S>(path: &[S]) -> Option<String>
where
S: PartialEq<&'a str>,
{
if path == ["a", "b"] {
return Some("It's a-b!".to_string())
}
None
}
但是如果我用 match
:
就不行了
pub fn info2<'a, S>(path: &[S]) -> Option<String>
where
S: PartialEq<&'a str>,
{
match path {
["a", "b"] => Some("It's a b!".to_string()),
_ => None,
}
}
error[E0308]: mismatched types
--> src/lib.rs:16:6
|
11 | pub fn info2<'a, S>(path: &[S]) -> Option<String>
| - this type parameter
...
15 | match path {
| ---- this expression has type `&[S]`
16 | ["a", "b"] => Some("It's a b!".to_string()),
| ^^^ expected type parameter `S`, found `&str`
|
= note: expected type parameter `S`
found reference `&'static str`
有什么办法让它起作用吗?理想情况下不需要像 ["a".as_foo(), "b".as_foo()]
.
这样的东西
您不能为此使用 match
。
你的第一个版本没有问题。您可以使用 higher-ranked trait bound (for<'a>
):
使其更通用
pub fn info1<S>(path: &[S]) -> Option<String>
where
for<'a> S: PartialEq<&'a str>,
{
if path == ["a", "b"] {
Some("It's a-b!".to_string());
} else {
None
}
}
我得到了一个有用的答案from the Rust Forum. It isn't possible to use match
because patterns in match
can only consist of struct
s, enum
s, slice
s and literals. The best description of that I found is here:
A pattern consists of some combination of the following:
- Literals
- Destructured arrays, enums, structs, or tuples
- Variables
- Wildcards
- Placeholders
在这种情况下,像 "a"
这样的字符串文字是 &str
,所以这确实是您可以 match
反对的唯一一种字符串(您可以看到人们基本上同样的问题,但没有切片 here)。在那种情况下,您可以在不分配的情况下解决它,因为您不需要构建引用切片 - 您只需要一个。
因为你肯定需要一片 &str
s 所以除了分配一个 Vec<&str>
as suggested by Skysch:
真的别无他法
pub fn info1<'a, S>(path: &[S]) -> Option<String>
where
S: AsRef<str>,
{
match &path.iter().map(|s| s.as_ref()).collect::<Vec<_>>()[..] {
["a", "b"] => Some("It's a b!".to_string()),
_ => None,
}
}
我认为即使使用 macro_rules!
你也无法使用 match
解决它。然而,可以制作一个使用 ==
的类似于 match
的宏。
我有一个函数可以根据切片取 &[&str]
或 &[String]
和 return 不同的值。如果我添加 PartialEq
约束,使用 ==
效果很好:
pub fn info1<'a, S>(path: &[S]) -> Option<String>
where
S: PartialEq<&'a str>,
{
if path == ["a", "b"] {
return Some("It's a-b!".to_string())
}
None
}
但是如果我用 match
:
pub fn info2<'a, S>(path: &[S]) -> Option<String>
where
S: PartialEq<&'a str>,
{
match path {
["a", "b"] => Some("It's a b!".to_string()),
_ => None,
}
}
error[E0308]: mismatched types
--> src/lib.rs:16:6
|
11 | pub fn info2<'a, S>(path: &[S]) -> Option<String>
| - this type parameter
...
15 | match path {
| ---- this expression has type `&[S]`
16 | ["a", "b"] => Some("It's a b!".to_string()),
| ^^^ expected type parameter `S`, found `&str`
|
= note: expected type parameter `S`
found reference `&'static str`
有什么办法让它起作用吗?理想情况下不需要像 ["a".as_foo(), "b".as_foo()]
.
您不能为此使用 match
。
你的第一个版本没有问题。您可以使用 higher-ranked trait bound (for<'a>
):
pub fn info1<S>(path: &[S]) -> Option<String>
where
for<'a> S: PartialEq<&'a str>,
{
if path == ["a", "b"] {
Some("It's a-b!".to_string());
} else {
None
}
}
我得到了一个有用的答案from the Rust Forum. It isn't possible to use match
because patterns in match
can only consist of struct
s, enum
s, slice
s and literals. The best description of that I found is here:
A pattern consists of some combination of the following:
- Literals
- Destructured arrays, enums, structs, or tuples
- Variables
- Wildcards
- Placeholders
在这种情况下,像 "a"
这样的字符串文字是 &str
,所以这确实是您可以 match
反对的唯一一种字符串(您可以看到人们基本上同样的问题,但没有切片 here)。在那种情况下,您可以在不分配的情况下解决它,因为您不需要构建引用切片 - 您只需要一个。
因为你肯定需要一片 &str
s 所以除了分配一个 Vec<&str>
as suggested by Skysch:
pub fn info1<'a, S>(path: &[S]) -> Option<String>
where
S: AsRef<str>,
{
match &path.iter().map(|s| s.as_ref()).collect::<Vec<_>>()[..] {
["a", "b"] => Some("It's a b!".to_string()),
_ => None,
}
}
我认为即使使用 macro_rules!
你也无法使用 match
解决它。然而,可以制作一个使用 ==
的类似于 match
的宏。