function - rust 封闭和fn不匹配

标签 function rust closures

我正在尝试执行功能语言中的正常操作,即{F#,SML,OCaml,Haskel ..}将函数作为输入和输出传递。
但是我认为在Rust类型系统方面我还没有退出。下面的代码是我的代码中出错的部分。简而言之,我正在制作一个包含函数的结构,该结构可以执行某些操作并返回可能出错的其他内容。或函数存在问题,因为我需要在将来的某个时候将其合并,从而需要将输入传递给我正在使用闭包的运行函数。我尝试使用Fn作为类型,但是它仍然使编译器遇到错误。

pub struct Pattern<T>{
   pat : fn(&str) -> Result<(T, &str),&'static str>
}

impl<T> Pattern<T> {
    pub fn run(self, input: &str) -> Result<(T,& str), &'static str> {
        (self.pat)(input)
    }

pub fn or(self, pat: Pattern<T>) -> Pattern<T> {
        Pattern {
            pat: |input| match self.run(input) {
                Ok(ret) => Ok(ret),
                Err(msg) => {
                    match pat.run(input) {
                        Ok(ret) => Ok(ret),
                        Err(msg) => Err(msg),
                    } 
                }
            }
        }  
    }
}

最佳答案

我对以下解决方案不是很自信,但是谁知道...
首先,在or()中,您尝试提供捕获的Pattern在需要功能(不捕获)的情况下关闭;如你所说
在您的问题中,Fn特性似乎更适合pat成员。
为了实际存储它,可以使用Box<dyn Fn( ...>
此外,run()or()方法使用了Pattern,因此
每个Pattern只能使用一次,这可能不是您想要的。
我建议改用引用。Pattern中生成的or由值返回(正确,
在我看来);那么它的闭包需要捕获的所有局部变量
(selfpat参数)必须是move d到闭包中。
由于我们现在有很多相互引用的Pattern
我们必须明确地处理生命周期。例如,两个Pattern结合or()必须超过生成的Pattern
这些约束在整个代码中传播。
最后,尝试说明main()中的用法。
(也许经验丰富的Rust程序员会发现一个更简单的方法
实现此目的的方式,或一些错误)

pub struct Pattern<'p, T> {
    pat: Box<dyn Fn(&str) -> Result<(T, &str), &'static str> + 'p>,
}

impl<'p, T> Pattern<'p, T> {
    pub fn run<'s>(
        &self,
        input: &'s str,
    ) -> Result<(T, &'s str), &'static str> {
        (self.pat)(input)
    }

    pub fn or<'a, 'b>(
        &'p self,
        pat: &'a Pattern<T>,
    ) -> Pattern<'b, T>
    where
        'p: 'b,
        'a: 'b,
    {
        Pattern {
            pat: Box::new(move |input| match self.run(input) {
                Ok(ret) => Ok(ret),
                Err(_msg) => match pat.run(input) {
                    Ok(ret) => Ok(ret),
                    Err(msg) => Err(msg),
                },
            }),
        }
    }
}

fn main() {
    let p1 = Pattern {
        pat: Box::new(|input| {
            if input.len() >= 4 {
                Ok((1, &input[0..4]))
            } else {
                Err("too short for p1")
            }
        }),
    };
    let p2 = Pattern {
        pat: Box::new(|input| {
            if input.len() >= 2 {
                Ok((2, &input[2..]))
            } else {
                Err("too short for p2")
            }
        }),
    };
    let p3 = p1.or(&p2);
    println!("p1: {:?}", p1.run("a"));
    println!("p2: {:?}", p2.run("a"));
    println!("p3: {:?}", p3.run("a"));
    println!("~~~~~~~~~~~~~~~~");
    println!("p1: {:?}", p1.run("abc"));
    println!("p2: {:?}", p2.run("abc"));
    println!("p3: {:?}", p3.run("abc"));
    println!("~~~~~~~~~~~~~~~~");
    println!("p1: {:?}", p1.run("abcdef"));
    println!("p2: {:?}", p2.run("abcdef"));
    println!("p3: {:?}", p3.run("abcdef"));

    /*
    p1: Err("too short for p1")
    p2: Err("too short for p2")
    p3: Err("too short for p2")
    ~~~~~~~~~~~~~~~~
    p1: Err("too short for p1")
    p2: Ok((2, "c"))
    p3: Ok((2, "c"))
    ~~~~~~~~~~~~~~~~
    p1: Ok((1, "abcd"))
    p2: Ok((2, "cdef"))
    p3: Ok((1, "abcd"))
    */
}

关于function - rust 封闭和fn不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63857277/

相关文章:

javascript - 指定 .constructor.name 为任意字符串

rust - 为什么我的 nom 解析器不消耗整个输入,而留下最后一 block 未解析?

rust - 为什么 `std::mem::drop` 与高级特征边界中的闭包 |_|() 不完全相同?

javascript - 我如何将这段代码放入可重用的函数中?

python - 输出列表中的所有负数

rust - 如何实现 `From<some trait' s 关联类型>?`

c++ - 如何使用 cxx crate 调用 C++ 构造函数?

javascript - 如何在子函数中返回一个值?

javascript - 关于一次性自重定义函数模式

javascript - 带有 php 元素的 javascript 计时器