【问题标题】:Method containing closure parameter expects wrong type?包含闭包参数的方法需要错误的类型?
【发布时间】:2020-04-27 08:24:23
【问题描述】:

我有一个结构,Parser,其中包含一个transformer - 一个用于修改其ParserState- 的函数和所说的ParserState

#[derive(Clone)]
pub struct Parser<F> 
where
    F: Fn(ParserState) -> ParserState
{
    pub transformer: F,
    pub state: ParserState
}

#[derive(Debug, PartialEq, Clone)]
pub struct ParserState {
    pub target: String,
    pub index: usize,
    pub result: Vec<String>, // the container of eventual results from the parsing, with Some(result) or None. Should be a vetor
    pub error: bool,            // whether we've encountered an error; index -> 0, Some(err_msg)
    pub err_msg: Option<String> // Eventual error message
}

定义一个.map() 方法,我假设我可以简单地使用一个闭包,并在其中引用解析器自己的状态作为将它作为参数传递给该闭包。此闭包将用作.map() 方法的参数。

impl<F> Parser<F>
where
    F: Fn(ParserState) -> ParserState 
{
    pub fn new(f: F) -> Self {
        // creating a new Parser just means deciding on which closure it applies
        Parser {
            transformer: f,
            state: ParserState {
                target: String::from(""),
                index: 0,
                result: vec![],
                error: false,
                err_msg: None
            }
        }
    }

    pub fn map<G>(&mut self, g: G) -> ()
    where
        G: Fn(ParserState) -> ParserState
    {
        self.state = g((self.state).clone())
    }

    pub fn run(mut self, corpus: String) -> Self {
        self.state.target = corpus;
        self.state = (self.transformer)(self.state);
        self
    }
}

我是这样使用的:

fn main() {
    let haystack: String = String::from("Hello!Goodbye!");
    let needle = String::from("Hello!");
    let str_parser = Parser::new(str_parser(needle));
    let closure = |mut state: ParserState| state.index = 0;
    let result = str_parser.run(haystack);
    let result = result.map(closure);
    let adv = ParserState {
        target: "Hello!Goodbye!".to_string(),
        index: 0,
        result: vec!["Hello!".to_string()],
        error: false,
        err_msg: None
    };
    assert_eq!(adv, result.state);
}

这没有奏效。我遇到了这个错误:

error[E0271]: type mismatch resolving `<[closure@src/lib.rs:49:23: 49:63] as std::ops::FnOnce<(parse
rs::ParserState,)>>::Output == parsers::ParserState`
  --> src/lib.rs:51:29
   |
51 |         let result = result.map(closure);
   |                             ^^^ expected `()`, found struct `parsers::ParserState`

我不确定我没有提到的FnOnce 是如何相关的。我也不明白.map() 如何期望() 作为参数,当它是Parser 的方法时。我觉得这里有点超出我的深度。

这是the relevant Rust playground的链接

【问题讨论】:

    标签: generics rust closures


    【解决方案1】:

    此闭包返回()(即它不返回值):

    let closure = |mut state: ParserState| state.index = 0;
    

    但是F 被声明为返回ParserState。您只需要让函数按预期返回值。

    let closure = |mut state: ParserState| {
        state.index = 0;
        state
    };
    

    我不确定我没有提到的FnOnce 是如何相关的。

    FnOnce 是最通用的函数特征;所有函数都至少可以调用一次,因此所有函数都实现FnOnce,但可能不实现FnFnMut。我认为它在错误消息中提到 FnOnce 的事实只是它尝试匹配类型的顺序的产物。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-05
      相关资源
      最近更新 更多