如何借用一个结构的库函数字段?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何借用一个结构的库函数字段?相关的知识,希望对你有一定的参考价值。

我有一个结构体。Parser 与场。transformer 是为了容纳一个函数。这个函数返回一个闭包,它处理一个 ParserState 并返回一个 ParserState. 我做了一个功能。str_parser的一个新实例的变压器。Parser.

pub struct Parser<F> 
    where F: FnOnce(ParserState) -> ParserState {
    pub transformer: F
}

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

impl<F> Parser<F> 
    where F: FnOnce(ParserState) -> ParserState {
    pub fn new(f: F) -> Self {
        // creating a new Parser just means deciding on which closure it applies
        Parser {
            transformer: f,
        }
    }

    pub fn run(&self, corpus: String) -> ParserState {
        let state = ParserState {
            target: corpus,
            index: 0,
            result: None,
            error: false,
            err_msg: None
        };
        return (self.transformer)(state);
    }
}

pub fn str_parser(needle: String) -> impl FnOnce(ParserState) -> ParserState {
    let parser = move |state: ParserState| {
        let target_string = state.target;
        let index = state.index;
        if target_string[index..needle.len()] == needle {
            ParserState {
                target: target_string,
                index: index + needle.len(),
                result: Some(needle),
                error: false,
                err_msg: None
            }
        } else {
            ParserState {
                target: String::from(""),
                index: 0,
                result: None,
                error: true,
                err_msg: Some(String::from("Error"))
            }
        }
    };
    parser
}

借款检查器拒绝让我将这个函数应用到提供的参数后咖,因为这个错误。

error[E0507]: cannot move out of `self.transformer` which is behind a shared reference
  --> src/parsers.rs:32:16
   |
32 |         return (self.transformer)(state);
   |                ^^^^^^^^^^^^^^^^^^ move occurs because `self.transformer` has type `F`, which does not implement the `Copy` trait

我应该怎么做?实现 Copy 特质在这种情况下,似乎让我望而生畏。有没有办法让这是一个合法的举动,同时还能让我做咖哩这个。str_parser 函数?

答案

在这种情况下,我有一个 Parser 的,没有任何其他状态。transformer. 因此,我不需要使用 FnOnce. Fn 是我所需要的。从那时起,我修改了我的 "我的 "中使用的封口。str_parser 函数来克隆 needle 弦。

pub struct Parser<F> 
    where F: Fn(ParserState) -> ParserState {
    pub transformer: F
}

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

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,
        }
    }

    pub fn run(&self, corpus: String) -> ParserState {
        let state = ParserState {
            target: corpus,
            index: 0,
            result: None,
            error: false,
            err_msg: None
        };
        return (self.transformer)(state);
    }
}

pub fn str_parser(needle: String) -> impl Fn(ParserState) -> ParserState {
    move |mut state: ParserState| {
        let target_string = state.target;
        let index = state.index;
        if target_string[index..needle.len()] == needle {
            state = ParserState {
                target: target_string,
                index: index + needle.len(),
                result: Some(needle.clone()),
                error: false,
                err_msg: None
            }
        } else {
            state = ParserState {
                target: String::from(""),
                index: 0,
                result: None,
                error: true,
                err_msg: Some(String::from("Error"))
            }
        }
        state
    }
}

以上是关于如何借用一个结构的库函数字段?的主要内容,如果未能解决你的问题,请参考以下文章

可变地借用一个结构字段,同时在闭包中借用另一个

ruby 我感兴趣的库中的代码片段

我如何使用视图模型从另一个片段访问函数

如何使用webpack加载库源映射?

如何使用非托管 C/C++ 结构和函数

VSCode自定义代码片段5——HTML元素结构