克隆存储闭包的结构[重复]

2023-11-25

我目前正在尝试用 Rust 实现一个简单的解析器组合器库。为此我想要一个通用的map转换解析器结果的函数。

问题是我不知道如何复制持有闭包的结构。一个例子是Map以下示例中的结构体。它有一个mapFunction存储函数的字段,该函数接收前一个解析器的结果并返回新的结果。Map本身就是一个解析器,可以与其他解析器进一步组合。

然而,为了组合解析器,我需要它们是可复制的(具有Clone特质绑定),但我如何提供这个Map?

示例:(只有伪代码,很可能无法编译)

trait Parser<A> { // Cannot have the ": Clone" bound because of `Map`.
    // Every parser needs to have a `run` function that takes the input as argument
    // and optionally produces a result and the remaining input.
    fn run(&self, input: ~str) -> Option<(A, ~str)>
}

struct Char {
    chr: char
}

impl Parser<char> for Char {
    // The char parser returns Some(char) if the first 
    fn run(&self, input: ~str) -> Option<(char, ~str)> {
        if input.len() > 0 && input[0] == self.chr {
            Some((self.chr, input.slice(1, input.len())))
        } else {
            None
        }
    }
}

struct Map<'a, A, B, PA> {
    parser: PA,
    mapFunction: 'a |result: A| -> B,
}

impl<'a, A, B, PA: Parser<A>> Parser<B> for Map<'a, A, B, PA> {
    fn run(&self, input: ~str) -> Option<(B, ~str)> {
        ...
    }
}

fn main() {
    let parser = Char{ chr: 'a' };
    let result = parser.run(~"abc");

    // let mapParser = parser.map(|c: char| atoi(c));

    assert!(result == Some('a'));
}

如果您引用闭包,这是可能的,因为您可以Copy参考。

一般来说,克隆封闭是不可能的。但是,您可以创建一个包含函数使用的变量的结构类型,派生Clone就可以了,然后执行Fn自己做吧。

引用闭包的示例:

// The parser type needs to be sized if we want to be able to make maps.
trait Parser<A>: Sized {
    // Cannot have the ": Clone" bound because of `Map`.
    // Every parser needs to have a `run` function that takes the input as argument
    // and optionally produces a result and the remaining input.
    fn run(&self, input: &str) -> Option<(A, String)>;

    fn map<B>(self, f: &Fn(A) -> B) -> Map<A, B, Self> {
        Map {
            parser: self,
            map_function: f,
        }
    }
}

struct Char {
    chr: char,
}

impl Parser<char> for Char {
    // These days it is more complicated than in 2014 to find the first
    // character of a string. I don't know how to easily return the subslice
    // that skips the first character. Returning a `String` is a wasteful way
    // to structure a parser in Rust.
    fn run(&self, input: &str) -> Option<(char, String)> {
        if !input.is_empty() {
            let mut chars = input.chars();
            let first: char = chars.next().unwrap();
            if input.len() > 0 && first == self.chr {
                let rest: String = chars.collect();
                Some((self.chr, rest))
            } else {
                None
            }
        } else {
            None
        }
    }
}

struct Map<'a, A: 'a, B: 'a, PA> {
    parser: PA,
    map_function: &'a Fn(A) -> B,
}

impl<'a, A, B, PA: Parser<A>> Parser<B> for Map<'a, A, B, PA> {
    fn run(&self, input: &str) -> Option<(B, String)> {
        let (a, rest) = self.parser.run(input)?;
        Some(((self.map_function)(a), rest))
    }
}

fn main() {
    let parser = Char { chr: '5' };
    let result_1 = parser.run(&"567");

    let base = 10;
    let closure = |c: char| c.to_digit(base).unwrap();

    assert!(result_1 == Some(('5', "67".to_string())));

    let map_parser = parser.map(&closure);
    let result_2 = map_parser.run(&"567");
    assert!(result_2 == Some((5, "67".to_string())));
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

克隆存储闭包的结构[重复] 的相关文章

随机推荐

  • 如何将值的数组参数输入到 Firebird 存储过程?

    我想输入一个数组参数ID 数为火鸟存储过程 INPUT LIST ID 1 2 12 45 75 45 我需要执行这个 SQL 命令 SELECT FROM CITY WHERE ID CITY IN INPUT LIST ID 是否可以
  • UIImage缩放后变得模糊。为什么?(iOS 5.0)

    UIImage缩放后总是变得模糊 如何才能保持清晰 UIImage rescaleImageToSize CGSize size CGRect rect CGRectMake 0 0 0 0 size width size height U
  • 从 ACF 相关图中提取置信区间值

    在 R 中 我们可以运行时间序列的 ACF 相关图 置信区间带将以浅蓝色绘制 但是当我拉取 ACF 对象的结构时 我找不到这些值 有谁知道如何提取置信区间带的值 e g List of 6 acf num 1 27 1 1 1 0 0645
  • 将 var 放入 jquery :gt()

    我有一个列表设置display none以及一些显示第 3 项的代码 HTML ul li item 1 li li item 2 li li item 3 li li item 4 li ul jquery var item 1 li g
  • 如何忽略 mod_rewrite 中的目录?

    我试图让 modrewrite 规则跳过该目录vip 我已经尝试了很多方法 如下所示 但没有成功 BEGIN WordPress
  • 将 VS Code Jupyter Notebook 中的输出折叠到可滚动窗口中

    有没有办法在 VS Code Jupyter Notebook 的可滚动窗口中显示输出 例如很长的数据帧 我知道按字母 o 可以折叠所有输出 但拥有可滚动窗口仍然更好 因为它允许您在引用其他窗口的同时检查输出 我也检查了这个link但无法让
  • 如何检查字符串中是否有特殊字符或者某个字符是否是GoLang中的特殊字符

    从输入读取字符串后 我需要检查其中是否有特殊字符 您可以使用 strings ContainsAny 来查看符文是否存在 package main import fmt strings func main fmt Println strin
  • numpy.genfromtxt 与 datetime.strptime 转换器

    我有与此类似的数据gist我正在尝试用 numpy 提取数据 我对 python 相当陌生 所以我尝试使用以下代码来做到这一点 import numpy as np from datetime import datetime convert
  • jQuery 追加如果不存在

    我想附加一个div仅当它尚不存在时 我正在尝试这样做 但它不起作用 method id on change function e if this find option selected data method column id 1 if
  • Java:静态类?

    我有一门充满实用功能的课程 实例化它的实例没有语义意义 但我仍然想调用它的方法 处理这个问题的最佳方法是什么 静态类 抽象的 标记为 Final 的类上的私有构造函数和静态方法
  • 为什么 ScheduledExecutorService 不根据需要生成线程?

    在我的应用程序中 我使用 ScheduledExecutorService 但仅生成一个线程来处理计划任务 这是因为 ScheduledExecutorService 不会生成线程来处理挂起的任务吗 下面是一个代码片段 它将仅输出 run
  • CUDA:为什么按位运算符有时比逻辑运算符更快?

    当我要从内核中榨取最后一点性能时 我通常会发现替换逻辑运算符 and with 按位运算符 and 使内核更快一些 这是通过查看 CUDA Visual Profiler 中的内核时间摘要观察到的 那么 为什么按位运算符faster比 CU
  • 如何更改shinydashboard中侧边栏的字体大小

    我是shinydashboard的新手 不熟悉CSS 谁能告诉我如何更改shinydashboard中侧边栏的字体大小 非常感谢 下面是我的代码 library shinydashboard library shiny ui lt dash
  • PHP 中的密码安全

    您认为哪种方法最安全 我从 php net 上取下了这些片段 我只是想知道 因为人们发布了自己的内容 而我只是无法理解为什么有些人是这样的 有人可以帮助我并告诉我更多关于这些的信息吗 哪个最安全 为什么 1 2
  • 为什么我们不能覆盖`||`和`&&`?

    大卫 A 布莱克他在书中指出 条件赋值运算符 以及它很少被发现的 表弟 两者都提供与伪操作符方法相同的快捷方式 但基于操作符 即 and 您无法覆盖它 为什么他特别提到我们不能覆盖 and 与对象上的其他一些运算符不同 对象的行为在逻辑上可
  • 如何与 Kronos API 进行通信?

    我有一个Kronos入口点http kronos wfc XmlService我应该能够访问 但是当我在浏览器中打开它时 响应是
  • 在字符串数组项元素中搜索字符串

    如何在字符串数组项元素内搜索特定文本 以下是 xml 文件的示例 字符串数组名称是 android 我在字符串数组中有一些项目 现在我想搜索 软件 这个词 请告诉我该怎么做
  • C# - 以编程方式推进 Powerpoint 幻灯片放映的方法?

    我希望能够通过按 Windows 窗体中的按钮来推进 Powerpoint 演示文稿 这是我找到的一些代码http bytes com topic c sharp answers 272940 open powerpoint present
  • LINQ to SQL 中的 Guid 类型和(“>”大于比较)

    请帮我 我尝试比较 Where 查询方法中的两个 guid 但我得到编译错误 错误 1 运算符 gt 不能应用于 System Guid 和 System Guid 类型的操作数 Guid startUser Here I get user
  • 克隆存储闭包的结构[重复]

    这个问题在这里已经有答案了 我目前正在尝试用 Rust 实现一个简单的解析器组合器库 为此我想要一个通用的map转换解析器结果的函数 问题是我不知道如何复制持有闭包的结构 一个例子是Map以下示例中的结构体 它有一个mapFunction存