【问题标题】:Explicitly cast a type that involves a specific function item type显式转换涉及特定功能项类型的类型
【发布时间】:2016-04-19 16:20:41
【问题描述】:

这是一个例子:

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

【问题讨论】:

    标签: function types rust coercion


    【解决方案1】:

    您实际上可以使用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不允许改变任意类型。


    就个人而言,我认为强制转换的必要性是一个缺点,并希望类型推断能够改进到它变得不必要的程度。它适用于直接回报的事实是一个红鲱鱼,它可能也适用于中间值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      相关资源
      最近更新 更多