Fn作为特性混凝土寿命要求

时间:2017-08-29 18:53:19

标签: rust

我想使用我可以修改的reg

struct Ctx;
trait Foo {}

trait Ex {
    fn do_<'a>(&self, cx: &'a mut Ctx) -> Box<Foo + 'a>;
}

impl<F> Ex for F
where
    F: for<'a> Fn(&'a mut Ctx) -> Box<Foo + 'a>,
{
    fn do_<'a>(&self, ecx: &'a mut Ctx) -> Box<Foo + 'a> {
        (*self)(ecx)
    }
}

fn reg<F>(name: &str, ext: F)
where
    F: Ex + 'static,
{
}

//My code starts here
struct Boo;

impl Boo {
    fn f1<'a>(&self, cx: &'a mut Ctx) -> Box<Foo + 'a> {
        unimplemented!();
    }
}

fn main() {
    let boo = Boo;
    reg("aaa", move |cx| boo.f1(cx));
}

但我收到了一个错误:

error[E0271]: type mismatch resolving `for<'a> <[closure@src/main.rs:33:16: 33:36 boo:_] as std::ops::FnOnce<(&'a mut Ctx,)>>::Output == std::boxed::Box<Foo + 'a>`
  --> src/main.rs:33:5
   |
33 |     reg("aaa", move |cx| boo.f1(cx));
   |     ^^^ expected bound lifetime parameter 'a, found concrete lifetime
   |
   = note: concrete lifetime that was found is lifetime '_#9r
   = note: required because of the requirements on the impl of `Ex` for `[closure@src/main.rs:33:16: 33:36 boo:_]`
   = note: required by `reg`

error[E0281]: type mismatch: `[closure@src/main.rs:33:16: 33:36 boo:_]` implements the trait `std::ops::Fn<(&mut Ctx,)>`, but the trait `for<'a> std::ops::Fn<(&'a mut Ctx,)>` is required
  --> src/main.rs:33:5
   |
33 |     reg("aaa", move |cx| boo.f1(cx));
   |     ^^^        -------------------- implements `std::ops::Fn<(&mut Ctx,)>`
   |     |
   |     requires `for<'a> std::ops::Fn<(&'a mut Ctx,)>`
   |     expected concrete lifetime, found bound lifetime parameter 'a
   |
   = note: required because of the requirements on the impl of `Ex` for `[closure@src/main.rs:33:16: 33:36 boo:_]`
   = note: required by `reg`

我该如何解决这个问题?

在实际代码中,struct Boo包含一些数据, 并希望两次致电reg,所以我没有实施trait Ex,但是 尝试使用闭包。

1 个答案:

答案 0 :(得分:1)

看起来像issue #38714

修复后,您可以直接为fail实施@interface ViewController () <UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout> @property (nonatomic,assign) CGFloat scale; @property (nonatomic,weak) IBOutlet UICollectionView *collectionView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.scale = 1.0; [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cell"]; UIPinchGestureRecognizer *gesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(didReceivePinchGesture:)]; [self.collectionView addGestureRecognizer:gesture]; } - (CGSize)collectionView:(UICollectionView *)collectionView layout: (UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath: (NSIndexPath *)indexPath { return CGSizeMake(50*self.scale, 50*self.scale); } - (void)didReceivePinchGesture:(UIPinchGestureRecognizer*)gesture { static CGFloat scaleStart; if (gesture.state == UIGestureRecognizerStateBegan) { scaleStart = self.scale; } else if (gesture.state == UIGestureRecognizerStateChanged) { self.scale = scaleStart * gesture.scale; [self.collectionView.collectionViewLayout invalidateLayout]; } }

Ex
  

在实际代码中我的struct Boo包含一些数据,并且想要两次调用reg,所以我没有实现trait Ex,但是尝试使用闭包。

您无法使用您提供的代码执行此操作。 Booimpl Ex for Boo { fn do_<'a>(&self, ecx: &'a mut Ctx) -> Box<Foo + 'a> { self.f1(ecx) } } fn main() { let boo = Boo; reg("aaa", boo); } 移至关闭位置,之后您无法使用move |cx| boo.f1(cx)

如果您想共享数据,则需要在boo中使用boo