显式转换涉及特定函数项类型的类型

时间:2016-01-14 11:01:40

标签: function types rust coercion

以下是一个例子:

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似乎有点矫枉过正,但我​​相信,它会起作用。

1 个答案:

答案 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不允许更改任意类型。

就个人而言,我认为演员的必要性是短暂的,并希望类型推断能够提升到不必要的程度。它适用于直接返回的事实是红鲱鱼,它也可能适用于中间值。