如何解决锈封闭和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
由值返回(正确,
在我看来);那么它的闭包需要捕获的所有局部变量
(self
和pat
参数)必须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 举报,一经查实,本站将立刻删除。