将FnMut上实现的特征传递给辅助函数而不移动

时间:2017-12-21 18:19:06

标签: rust

我正在尝试使用一组可以采用CharPredicate的函数,这是我自己在FnMut(char) -> boolRange<char>char上实现的特征,等

目标是能够像这样召唤助手:

scan_until(';');
scan_while('0'..='9');
scan_while(|c| { c.is_digit() });

对于其中一些帮助程序,我想多次调用它们并在函数之间传递它们。但是,借用这个例子,借用检查员对我很生气:

#![feature(fn_traits)]

pub fn helper<P: CharPredicate>(mut predicate: P) -> bool {
    predicate.test('a')
}

pub fn scan_until<P: CharPredicate>(mut predicate: P) {
    // [A] This works
    while predicate.test('a') {}

    // [B] This doesn't: Use of moved value `predicate`
    //while helper(predicate) {}

    // [C] This doesn't either: the trait bound `P: std::ops::FnMut<(char,)>` is not satisfied
    //while helper(&mut predicate) {}
}

pub trait CharPredicate {
    fn test(&mut self, c: char) -> bool;
}

impl<F: FnMut(char) -> bool> CharPredicate for F {
    fn test(&mut self, c: char) -> bool {
        self.call_mut((c,))
    }
}

Playground

案例 A 有效;我可以在循环中多次调用谓词。

案例 B 失败,因为我在第一次迭代中将谓词移动到帮助器中。这对我来说很有意义。

案例 C 是我尝试修复B以便它可以正常工作,我想传递对闭包的引用以允许它被调用。

helper更改为&mut P确实允许Case C 工作,但也可以直接调用helper,这意味着调用者必须{ {1}}在他们所做的每一个电话面前。我尝试了&mut,但结果是使用impl<P: CharPredicate> CharPredicate for &mut P版本的特征冲突。

这是我可以工作的东西,还是我必须在我的帮助函数中使用FnMut

1 个答案:

答案 0 :(得分:0)

如果闭包是特征的有效实现,那么进行闭包:

pub fn scan_until<P: CharPredicate>(mut predicate: P) {
    while helper(|c| predicate.test(c)) {}
}