types - 是否可以将闭包分配给 impl Fn() 类型的变量?

标签 types rust closures

我能够使这段代码工作:

fn twice<T: Clone>(fst: impl Fn(T), snd: impl Fn(T)) -> impl Fn(T) {
    move |t| {
        fst(t.clone());
        snd(t)
    }
}

然而,我想要的是这个(没有装箱):

fn sub<T: Clone>(mut fst: impl Fn(T), snd: impl Fn(T)) {
    fst = move |t: T| {
        fst(t.clone());
        snd(t)
    };
}

有没有一种方法可以使第二段代码无需装箱、使用特征、类型转换或任何其他方法就可以工作? Rust 提示类型不匹配。

最佳答案

如果没有装箱,这是做不到的。原因是输入中 fst 的实际类型与您稍后覆盖它的闭包类型不同。使它们成为同一类型的唯一方法是使用特征对象。

盒装版本可能如下所示:

use std::mem;

fn sub<'a, T: Clone + 'a>(fst: &mut Box<dyn Fn(T) + 'a>, snd: impl Fn(T) + 'a) {
    // Replace the original fst with a dummy closure while the new closure is being
    // constructed, to avoid the reference being temporarily invalid
    let fst_orig = mem::replace(fst, Box::new(|_| {}));
    *fst = Box::new(move |t: T| {
        fst_orig(t.clone());
        snd(t)
    });
}


fn main() {
    let mut f1: Box<dyn Fn(i32)> = Box::new(|x| println!("f1: {}", x));
    let f2 = |x| println!("f2: {}", x);

    sub(&mut f1, f2);

    f1(42);
}

但我真的不确定你为什么要这样做!

关于types - 是否可以将闭包分配给 impl Fn() 类型的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54269942/

相关文章:

haskell - Haskell 中的类型匹配

rust - 使用格式化宏时如何编写文字引号?

generics - 通过关联类型返回泛型

javascript - Swift 中的闭包概念是否类似于 Javascript 中的闭包?

JavaScript:函数及其作用域/词法环境如何传递?

java - 如何创建一个名为“标识符”的新数据类型,使其每个实例都应该是有效的标识符名称?

language-agnostic - 什么是类型?

rust - 是否可以将函数类型从签名中移出并移到 where 子句中?

javascript - Firefox 22.0 范围错误?

typescript - TypeScript 中可以使用编译时标记数字吗?