这个问题在这里已有答案:
有没有任何方法可以绑定(而不是定义)可能的递归函数?例如:
type F = fn(i32) -> i32;
// equivalent to |x| (x+1)*2
fn f: F = composite(add_by(1), mult_by(2));
// equivalent to |x| if x > 100 then {x} else {g(x*2)}
// note the recursion
fn g: F = branch(greater_than(100), identity, composite(mult_by(2), g));
我试图实现的递归不是一般的闭包(问here),这在没有黑客的情况下是不可能的,而只是一个具有更好语法的正常函数(类型签名和定义)。
当type F
复杂并且应该被抽象地使用时,这可能是有用的,例如,
type Parser<T> = fn(&str) -> Option<(T, &str)>
我没有看到add_by
,mult_by
或composite
如何返回除闭包之外的任何东西,因为返回的“东西”必须记住(例如“捕获”)参数......
话虽这么说,如果你做add_by
和co,你可以使它工作。到宏而不是函数:
macro_rules! add_by {
($y:expr) => { { fn f (x: i32) -> i32 { x + $y } f } }
}
macro_rules! less_than {
($y:expr) => { { fn f (x: i32) -> bool { x < $y } f } }
}
macro_rules! compose {
($f:expr, $g:expr) => { { fn c (x: i32) -> i32 { $f ($g (x)) } c } }
}
macro_rules! branch {
($rec:ident, $test:expr, $if_true:expr, $if_false:expr) => {
{
fn $rec (x: i32) -> i32 {
if $test (x) { $if_true (x) } else { $if_false (x) }
}
$rec
}
}
}
fn main() {
let g = branch!(g, less_than!(10), add_by!(1), compose!(add_by!(1), g));
println!("Test: {}", g(4));
}
这里的重点是你需要将递归函数的名称作为参数提供给branch
宏(参数$rec
),此时你可以从子表达式访问它。