【问题标题】:How to use closure instead of trait?如何使用闭包而不是特征?
【发布时间】:2017-07-23 19:38:57
【问题描述】:

我想注册Gen::my_g 作为回调。简单的方法是为Gen实现trait Foo,但我不想为Gen实现trait Foo

也就是说,我想注释掉标记为B!!!的代码,并取消注释标记为A!!!的代码。

这不是我的代码;我不能修改这个:

struct S1;

struct TT;
trait MyRes {}

trait Foo {
    fn g<'a>(&self, ecx: &'a mut S1, tt: &[TT]) -> Box<MyRes + 'a>;
}

impl<F> Foo for F
where
    F: for<'a> Fn(&'a mut S1, &[TT]) -> Box<MyRes + 'a>,
{
    fn g<'a>(&self, ecx: &'a mut S1, tt: &[TT]) -> Box<MyRes + 'a> {
        (*self)(ecx, tt)
    }
}

fn f1<F>(name: &str, extension: F)
where
    F: Foo + 'static,
{
}

这是我的代码:

struct Gen {}
impl Gen {
    fn register(self) {

        //        f1("aaa", move |ecx, tt| self.my_g(ecx, tt));//A!!!

        f1("aaa", self); //B!!!
    }

    fn my_g<'a>(&self, ecx: &'a mut S1, tt: &[TT]) -> Box<MyRes + 'a> {
        unimplemented!();
    }
}

impl Foo for Gen {
    fn g<'a>(&self, ecx: &'a mut S1, tt: &[TT]) -> Box<MyRes + 'a> {
        self.my_g(ecx, tt)
    }
}

如果我取消注释 //A!!!,编译器会告诉我一些我不理解的内容:

error[E0271]: type mismatch resolving `for<'a, 'r> <[closure@src/main.rs:29:19: 29:52 self:_] as std::ops::FnOnce<(&'a mut S1, &'r [TT])>>::Output == std::boxed::Box<MyRes + 'a>`
  --> src/main.rs:29:9
   |
29 |         f1("aaa", move |ecx, tt| self.my_g(ecx, tt)); //A!!!
   |         ^^ expected bound lifetime parameter, found concrete lifetime
   |
   = note: concrete lifetime that was found is lifetime '_#12r
   = note: required because of the requirements on the impl of `Foo` for `[closure@src/main.rs:29:19: 29:52 self:_]`
   = note: required by `f1`

error[E0281]: type mismatch: `[closure@src/main.rs:29:19: 29:52 self:_]` implements the trait `std::ops::Fn<(&mut S1, &[TT])>`, but the trait `for<'a, 'r> std::ops::Fn<(&'a mut S1, &'r [TT])>` is required
  --> src/main.rs:29:9
   |
29 |         f1("aaa", move |ecx, tt| self.my_g(ecx, tt)); //A!!!
   |         ^^        --------------------------------- implements `std::ops::Fn<(&mut S1, &[TT])>`
   |         |
   |         requires `for<'a, 'r> std::ops::Fn<(&'a mut S1, &'r [TT])>`
   |         expected concrete lifetime, found bound lifetime parameter
   |
   = note: required because of the requirements on the impl of `Foo` for `[closure@src/main.rs:29:19: 29:52 self:_]`
   = note: required by `f1`

【问题讨论】:

  • stackoverflow.com/q/31362206/2731452 的副本在您的情况下,您可以使用 fn constrain_handler&lt;F&gt;(f: F) -&gt; F where F: for&lt;'a&gt; Fn(&amp;'a mut S1, &amp;[TT]) -&gt; Box&lt;MyRes + 'a&gt; { f }

标签: rust


【解决方案1】:

这是一个已知问题:

Rust 编译器目前无法推断闭包在任何生命周期内都有效(这是 Foo::g 的类型所要求的)。它会推断出任何具体的生命周期,但不会进行推广。

【讨论】:

    猜你喜欢
    • 2018-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-31
    相关资源
    最近更新 更多