包含闭包参数的方法期望类型错误?

问题描述 投票:0回答:1

我有一个结构体。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. 我觉得自己有点力不从心。

这里有一个链接 相关的Rust游乐场

generics rust closures
1个回答
2
投票

这个闭包返回 () 即它不返回一个值)。

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

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

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

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

FnOnce 是最通用的函数特性;所有的函数至少可以被调用一次,所以所有的函数都实现了 FnOnce但可能不执行 FnFnMut. 我认为事实上,它提到了 FnOnce 中的错误信息只是它在尝试匹配类型时的顺序造成的。

© www.soinside.com 2019 - 2024. All rights reserved.