我正在尝试使用返回向量中字符串的引用的键函数对Vec<String>
进行排序。一个人为的示例是使用身份函数作为键函数(当然是无用的,但这是复制我的问题的最小示例):
fn key(x: &String) -> &String {
x
}
fn example(items: Vec<String>) {
items.sort_by_key(key);
}
这会产生以下错误:
error[E0308]: mismatched types
--> src/lib.rs:6:11
|
6 | items.sort_by_key(key);
| ^^^^^^^^^^^ lifetime mismatch
|
= note: expected associated type `<for<'r> fn(&'r String) -> &'r String {key} as FnOnce<(&String,)>>::Output`
found associated type `<for<'r> fn(&'r String) -> &'r String {key} as FnOnce<(&String,)>>::Output`
= note: the required lifetime does not necessarily outlive the empty lifetime
note: the lifetime requirement is introduced here
我不明白为什么会出现这个错误,所以我试图追踪它。我首先实现了自己的sort_by_key()
函数:
fn sort_by_key<T, K: Ord>(a: &mut [T], key: fn(&T) -> K) {
a.sort_by(|x, y| key(x).cmp(&key(y)));
}
尝试调用此函数时,我遇到了一个看起来像“相反”的错误:
error[E0308]: mismatched types
--> src/lib.rs:6:29
|
6 | sort_by_key(&mut items, key);
| ^^^ one type is more general than the other
|
= note: expected fn pointer `for<'r> fn(&'r String) -> &String`
found fn pointer `for<'r> fn(&'r String) -> &'r String`
我可以通过将键类型修复为 &T
而不是使用通用参数 K
,或者使用 &K
作为键函数的返回类型来使此代码编译:
fn sort_by_key_v2<T: Ord>(a: &mut [T], key: fn(&T) -> &T) {
a.sort_by(|x, y| key(x).cmp(&key(y)));
}
fn sort_by_key_v3<T, K: Ord>(a: &mut [T], key: fn(&T) -> &K) {
a.sort_by(|x, y| key(x).cmp(&key(y)));
}
我也尝试添加生命周期注释,但仅仅是将错误转移,而没有解决它。
这里是 Playground 上 sort_by_key()
函数的三个版本。
为什么会出现这些错误?有没有办法在完全保持键类型 K
的通用性的同时解决这些错误?
sort_by_key()
函数(更不用说无缝升级现有的sort_by_key()
函数了)。根据问题评论,其他夜版功能也是必需的,比如unboxed_closures
和下一代特质求解器。 - user4815162342