我正在尝试执行功能语言中的正常操作,即{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
由值返回(正确,
在我看来);那么它的闭包需要捕获的所有局部变量
(self
和pat
参数)必须是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/