如何在不克隆的情况下对 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`

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=72a529fa5b0d39997d5e3738db9c291a

我试过的

我也尝试过创建一个函数而不是闭包,这样我就可以为输入参数和输出分配相同的生命周期 (See playground),但随后我收到有关签名无效的错误消息。

一个可编译的解决方案 (See playground) 是克隆 Cow 如果 CowBorrowed 就很好,但如果不是 [=19] =] 那么为什么我需要克隆底层 String?我不能把 DerefString 调用成 &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

那么在这种情况下就可以了。但事实并非如此,所以我们必须忍受它:/