如何在不克隆的情况下对 Vec<(Cow<str>, Cow<str>) by_key 进行排序?
How to sort a Vec<(Cow<str>, Cow<str>) by_key without cloning?
我有一个包含键值对的元组向量,我想按键对它们进行排序。我想避免在 Cow
上调用 .to_string()
。我似乎找不到不克隆的方法。
use std::borrow::Cow;
fn main() {
let mut v: Vec<(Cow<str>, Cow<str>)> = vec![("a".into(), "xd".into()), ("0".into(), "xy".into())];
v.sort_by_key(|(k,_v)| k);
dbg!(v);
}
Compiling playground v0.0.1 (/playground)
error: lifetime may not live long enough
--> src/main.rs:4:28
|
4 | v.sort_by_key(|(k,_v)| k);
| ------- ^ returning this value requires that `'1` must outlive `'2`
| | |
| | return type of closure is &'2 Cow<'_, str>
| has type `&'1 (Cow<'_, str>, Cow<'_, str>)`
error: aborting due to previous error
error: could not compile `playground`
我试过的
我也尝试过创建一个函数而不是闭包,这样我就可以为输入参数和输出分配相同的生命周期 (See playground),但随后我收到有关签名无效的错误消息。
一个可编译的解决方案 (See playground) 是克隆 Cow
如果 Cow
是 Borrowed
就很好,但如果不是 [=19] =] 那么为什么我需要克隆底层 String
?我不能把 Deref
和 String
调用成 &str
吗?
也尝试显式匹配不同的 Cow
变体,但错误与第一个(See playground)非常相似。
错误信息
最重要的是我不理解错误消息:“返回此值要求 '1
必须比 '2
长”。好的,我接受这是必需的,但为什么这是一个错误?
首先,我将简化您的代码,原因有二:
- 让它更地道
- 并删除不必要的代码
fn main() {
let mut vector : Vec<(String, String)> = vec![(String::from("a"), String::from("xd")), (String::from("0"), String::from("xy"))];
dbg!(vector);
}
到目前为止,还不错。
为了避免方法调用 .to_string() 对向量进行排序,我们可以使用函数 sort_by代码(见playground):
vector.sort_by(|(k1, _), (k2, _)| k1.cmp(k2));
请注意,函数 cmp 不是 return 密钥的副本,而是函数 cmp return 的一个排序:
pub fn cmp(&self, other: &Self) -> Ordering
排序表示比较值 X [小于、等于、大于] 另一个 Y ( X.cmp(Y) )。
其他选项是使用函数 partial_cmp:
vector.sort_by(|(k1, _), (k2, _)| k1.partial_cmp(k2).unwrap());
函数 partial_cmp return 是一个 Option<Ordering> 枚举。这是因为我们使用了unwrap方法。
另一个选项(不能如你所愿地解决问题)是使用函数 sort_by_key:
vector.sort_by_key(|(k1, _)| String::from(k1));
但是因为这个函数return是key,所以需要新建一个来避免生命周期的问题。
只需使用 sort_by
而不是 sort_by_key
:
v.sort_by(|(k1, _), (k2, _)| k1.cmp(k2));
Most of all I don't understand the error message
问题是sort_by_key
's function declaration:
pub fn sort_by_key<K, F>(&mut self, f: F)
where
F: FnMut(&T) -> K,
K: Ord
这表明 sort_by_key
接受 returns 类型 K
的闭包,并且 &T
不必长于 K
。如果它被定义为
pub fn sort_by_key<'a, K, F>(&mut self, f: F)
where
F: FnMut(&'a T) -> K,
K: Ord + 'a
那么在这种情况下就可以了。但事实并非如此,所以我们必须忍受它:/
我有一个包含键值对的元组向量,我想按键对它们进行排序。我想避免在 Cow
上调用 .to_string()
。我似乎找不到不克隆的方法。
use std::borrow::Cow;
fn main() {
let mut v: Vec<(Cow<str>, Cow<str>)> = vec![("a".into(), "xd".into()), ("0".into(), "xy".into())];
v.sort_by_key(|(k,_v)| k);
dbg!(v);
}
Compiling playground v0.0.1 (/playground)
error: lifetime may not live long enough
--> src/main.rs:4:28
|
4 | v.sort_by_key(|(k,_v)| k);
| ------- ^ returning this value requires that `'1` must outlive `'2`
| | |
| | return type of closure is &'2 Cow<'_, str>
| has type `&'1 (Cow<'_, str>, Cow<'_, str>)`
error: aborting due to previous error
error: could not compile `playground`
我试过的
我也尝试过创建一个函数而不是闭包,这样我就可以为输入参数和输出分配相同的生命周期 (See playground),但随后我收到有关签名无效的错误消息。
一个可编译的解决方案 (See playground) 是克隆 Cow
如果 Cow
是 Borrowed
就很好,但如果不是 [=19] =] 那么为什么我需要克隆底层 String
?我不能把 Deref
和 String
调用成 &str
吗?
也尝试显式匹配不同的 Cow
变体,但错误与第一个(See playground)非常相似。
错误信息
最重要的是我不理解错误消息:“返回此值要求 '1
必须比 '2
长”。好的,我接受这是必需的,但为什么这是一个错误?
首先,我将简化您的代码,原因有二:
- 让它更地道
- 并删除不必要的代码
fn main() {
let mut vector : Vec<(String, String)> = vec![(String::from("a"), String::from("xd")), (String::from("0"), String::from("xy"))];
dbg!(vector);
}
到目前为止,还不错。
为了避免方法调用 .to_string() 对向量进行排序,我们可以使用函数 sort_by代码(见playground):
vector.sort_by(|(k1, _), (k2, _)| k1.cmp(k2));
请注意,函数 cmp 不是 return 密钥的副本,而是函数 cmp return 的一个排序:
pub fn cmp(&self, other: &Self) -> Ordering
排序表示比较值 X [小于、等于、大于] 另一个 Y ( X.cmp(Y) )。
其他选项是使用函数 partial_cmp:
vector.sort_by(|(k1, _), (k2, _)| k1.partial_cmp(k2).unwrap());
函数 partial_cmp return 是一个 Option<Ordering> 枚举。这是因为我们使用了unwrap方法。
另一个选项(不能如你所愿地解决问题)是使用函数 sort_by_key:
vector.sort_by_key(|(k1, _)| String::from(k1));
但是因为这个函数return是key,所以需要新建一个来避免生命周期的问题。
只需使用 sort_by
而不是 sort_by_key
:
v.sort_by(|(k1, _), (k2, _)| k1.cmp(k2));
Most of all I don't understand the error message
问题是sort_by_key
's function declaration:
pub fn sort_by_key<K, F>(&mut self, f: F)
where
F: FnMut(&T) -> K,
K: Ord
这表明 sort_by_key
接受 returns 类型 K
的闭包,并且 &T
不必长于 K
。如果它被定义为
pub fn sort_by_key<'a, K, F>(&mut self, f: F)
where
F: FnMut(&'a T) -> K,
K: Ord + 'a
那么在这种情况下就可以了。但事实并非如此,所以我们必须忍受它:/