【问题标题】:Rust type mismatch resolving `for<'r> ...` with closure trait alias argument使用闭包特征别名参数解决 `for<'r> ...` 的 Rust 类型不匹配
【发布时间】:2020-05-08 03:19:37
【问题描述】:

Trait 别名现在还不是稳定的 Rust,但我尝试通过这样做来模拟它们(给特定类型的闭包起一个更好的名字)

trait MyCallback: FnMut(&u32) -> () { }

impl<F: FnMut(&u32) -> ()> MyCallback for F { }

这对于我需要的其他类型的特征别名非常有用。但是当我尝试使用 trait 别名时,我遇到了无法解决的终身问题(?)。考虑以下两个重复的函数,只是在第二种情况下将MyCallback 替换为其“定义”。

fn process_data(mut f: impl MyCallback) -> () {
    f(&0)
}

fn process_data_2(mut f: impl FnMut(&u32) -> ()) -> () {
    f(&0)
}

fn main() {
    // Doesn't compile
    process_data(|_| ());

    // Compiles
    process_data_2(|_| ());
}

Playground 上的完整示例。) 正如所评论的,使用别名的函数不会接受我要传递的参数。我想我需要在特征定义中手动插入一些生命周期来模拟编译器在解析 process_data_2 时隐式执行的操作,但我不知道如何继续(我尝试插入 for&lt;'a&gt; 子句,我刚刚了解到的,都失败了)。

如何编译我的代码?

【问题讨论】:

    标签: rust closures traits lifetime


    【解决方案1】:

    要使其编译,您可以在闭包中添加类型注释:

    process_data(|_: &u32| ());
    

    这似乎与this longstanding issue有关。

    【讨论】:

    • 谢谢。该问题中还链接了this one,其中指出(一个非常相关的问题)由于当前的类型检查器设计而无法修复。
    【解决方案2】:

    如果我理解您的帖子,您正在尝试使用该特征来创建“回调”类型。如果确实是 ,那么最好使用函数别名,如下所示:

    pub type MyCallback = fn(&u32) -> ();
    
    fn process_data(mut f: MyCallback) -> () {
        f(&0)
    }
    

    您收到的错误消息是由于 nnnmmm 在上面发布的问题......就在我输入这篇文章时:p

    【讨论】:

    • 问题是我希望f: MyCallback 具有内部可变状态并被多次调用,我将其撕掉以制作 MRE。不过感谢您的帮助!
    猜你喜欢
    • 2015-11-20
    • 1970-01-01
    • 1970-01-01
    • 2016-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多