微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

锈封闭和fn不匹配

如何解决锈封闭和fn不匹配

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

    candidatos = list(
"name","score","tot_sFieldGoalsMade","tot_sFieldGoalsAttempted","tot_sTwoPointersMade","tot_sTwoPointersAttempted","tot_sThreePointersMade","tot_sThreePointersAttempted","tot_sFreeThrowsMade","tot_sFreeThrowsAttempted","tot_sReboundsDefensive","tot_sReboundsOffensive","tot_sReboundsTotal","tot_sAssists","tot_sBlocks","tot_sTurnovers","tot_sFoulsPersonal","tot_sPointsInThePaint","tot_sPointsSecondChance","tot_sPointsFromTurnovers","tot_sBenchPoints","tot_sPointsFastBreak","tot_sSteals"
)

 ListColum<-map(candidatos,function(x){
    as.data.frame(data$tm$"2"$x)
     } )

解决方法

我对以下解决方案不是很自信,但是谁知道...

首先,在or()中,您尝试提供结果Pattern的捕获 在需要功能(不捕获)的情况下关闭;如你所说 在您的问题中,Fn特质似乎更适合pat成员。 为了实际存储它,可以使用Box<dyn Fn( ...>

此外,run()or()方法消费 Pattern s,因此 每个Pattern只能使用一次,这可能不是您想要的。 我建议改用引用。

Pattern中产生的or由值返回(正确, 在我看来);那么它的闭包需要捕获的所有局部变量 (selfpat参数)必须move添加到闭包中。

由于我们现在有很多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"))
    */
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。