我试图使用一个键函数对Vec<String>
进行排序,该函数返回对向量中字符串的引用.一个人为的例子是使用身份函数作为关键函数(这当然是无用的,但这是重现我的问题的最小例子):
fn key(x: &String) -> &String {
x
}
现在给我items: Vec<String>
,我希望能做到
items.sort_by_key(key);
这会产生以下错误:
error[E0271]: type mismatch resolving `for<'r> <fn(&std::string::String) -> &std::string::String {main::key} as std::ops::FnOnce<(&'r std::string::String,)>>::Output == _`
--> src/main.rs:19:11
|
19 | items.sort_by_key(key);
| ^^^^^^^^^^^ expected bound lifetime parameter, found concrete lifetime
|
= note: concrete lifetime that was found is lifetime '_#16r
我不明白为什么我会犯这个错误,所以我试着找出原因.我首先实现了自己版本的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/main.rs:22:29
|
22 | sort_by_key(&mut items, key);
| ^^^ expected concrete lifetime, found bound lifetime parameter
|
= note: expected type `fn(&std::string::String) -> _`
found type `fn(&std::string::String) -> &std::string::String {main::key}`
我可以通过将键类型固定为&T
而不是使用泛型参数K
,或者使用&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)));
}
我还try 添加生存期注释,但这只会改变错误,而不会解决它.
Here's the three versions of the sort_by_key()
function on the Playground
为什么我会犯这些错误?有没有办法在保持密钥类型K
完全通用的同时修复它们?