以下是一个例子:
use std::iter::Filter;
use std::slice::Iter;
fn test(xs: &[i32]) -> Filter<Iter<i32>, fn(&&i32) -> bool> {
fn nothing(_: &&i32) -> bool { false }
let ys = xs.iter().filter(nothing);
ys
}
fn main () {
}
编译失败:
src/main.rs:8:5: 8:7 error: mismatched types:
expected `core::iter::Filter<core::slice::Iter<'_, i32>, fn(&&i32) -> bool>`,
found `core::iter::Filter<core::slice::Iter<'_, i32>, fn(&&i32) -> bool {test1::nothing}>`
(expected fn pointer,
found fn item) [E0308]
src/main.rs:8 ys
^~
这是因为ys
的推断类型具有type of a specific function item in it。在这种特殊情况下,问题很容易解决:可以在绑定中没有函数项的情况下显式指定类型,或者完全避免使用let
。
这两项工作都是:
fn test(xs: &[i32]) -> Filter<Iter<i32>, fn(&&i32) -> bool> {
fn nothing(_: &&i32) -> bool { false }
let ys: Filter<Iter<i32>, fn(&&i32) -> bool> = xs.iter().filter(nothing);
ys
}
fn test(xs: &[i32]) -> Filter<Iter<i32>, fn(&&i32) -> bool> {
fn nothing(_: &&i32) -> bool { false }
xs.iter().filter(nothing)
}
因此,正如参考文献所说,Rust确实能够自己执行这种强制。但是,如果代码更复杂并且我必须手动执行此转换,该怎么办?我该怎么做?
在这种情况下,as
无效,而transmute
似乎有点矫枉过正,但我相信,它会起作用。
答案 0 :(得分:3)
您实际上可以使用as
投射:
fn test(xs: &[i32]) -> Filter<Iter<i32>, fn(&&i32) -> bool> {
fn nothing(_: &&i32) -> bool { false }
let ys = xs.iter().filter(nothing as fn(&&i32) -> bool);
^~~~~~~~~~~~~~~~~~~~
ys
}
但是,您需要使用as
来更改函数的类型,而不是Filter
类型,因为as
不允许更改任意类型。
就个人而言,我认为演员的必要性是短暂的,并希望类型推断能够提升到不必要的程度。它适用于直接返回的事实是红鲱鱼,它也可能适用于中间值。