是否有一种惯用的Rust方法来绑定函数参数并生成一个新函数?
例如,假设我有以下功能:
fn eq(a: i32) -> Box<Fn(i32) -> bool> {
let target = a; // copy
Box::new(move |value| value == target)
}
fn evaluate(func: Box<Fn(i32) -> bool>, value: i32) -> bool {
func(value)
}
Box
使用的eq
机制是一种将参数绑定到函数的合理方式,以便在evaluate
中使用吗?例如像这样的东西:
let is_42 = eq(42);
assert_eq!(true, evaluate(is_42, 42));
还有生命的问题。我想知道在target
中延长eq()
的生命周期的正确语义是什么,所以它的生命周期与盒装函数的生命周期绑定。
答案 0 :(得分:5)
是否有一种惯用的Rust方法来绑定函数参数并生成一个新函数?
是的,Rust有闭包,它实际上是函数+绑定环境。
因此,绑定一个函数参数或部分应用它只是形成一个闭包,它将用一些固定的参数调用这个函数。
Box
使用eq
机制是一种将参数绑定到函数的合理方式,以便在evaluate
中使用吗?
现在是。
Rust关闭的问题是它们是Voldemort类型(即,无法命名的类型)。因此,虽然您可以为局部变量分配闭包,并让推断推断出类型,但您实际上无法从函数 1 返回它。
目前,解决方案是在这种情况下返回-> Box<Fn(..) -> ..>
。
但是,evaluate
的签名是不必要的约束。您可以参考:
Box
fn evaluate(f: &Fn(i32) -> bool, value: i32) -> bool { f(value) }
这将让可以直接调用evaluate
的用户免费在堆上分配(Box
执行)。
1 正在进行的工作允许将返回类型指定为-> impl SomeTrait
,这样您就可以这样做。
还有生命的问题。我想知道在
target
中延长eq()
的生命周期的正确语义是什么,所以它的生命周期与盒装函数的生命周期绑定。
无法延长一生;一生是描述性的,而不是规定性的:它只是表示实际生命周期的符号,而不是指定值应该具有的生命周期的方式。
对于闭包,你可能想要在闭包内move
他们的环境;采取价值而不是参考。它应该解决大多数终身问题。
对于剩余的生命周期问题,您实际上是反过来并通过表示其环境的生命周期来约束闭包的类型:F: Fn(i32) -> bool + 'a
标记F
仅对{{1}有效}}