从函数返回一个闭包 [英] Return a closure from a function
问题描述
请注意,此问题与发布1.0之前的Rust版本有关。
Note that this question pertains to a version of Rust before 1.0 was released
正确地说,现在不可能从函数返回一个闭包,除非它被提供给函数的参数?这是非常有用的方法,例如,当我需要相同的代码块,参数化不同,在程序的不同部分。目前编译器不允许这样的,自然地:
Do I understand correctly that it is now impossible to return a closure from a function, unless it was provided to the function in its arguments? It is very useful approach, for example, when I need the same block of code, parameterized differently, in different parts of program. Currently the compiler does not allow something like this, naturally:
fn make_adder(i: int) -> |int| -> int {
|j| i + j
}
闭包分配在堆栈上,一个函数,所以不可能返回它。
The closure is allocated on the stack and is freed upon returning from a function, so it is impossible to return it.
是否可以使这项工作在未来?我听说动态大小的类型会允许这样。
Will it be possible to make this work in future? I heard that dynamically-sized types would allow this.
推荐答案
它需要没有环境或自己的环境。 DST建议包括重新引入具有所有环境(〜Fn
)的闭包类型的可能性,这将满足您的需要,但尚不清楚是否会发生
This can't ever work for a stack closure; it needs to either have no environment or own its environment. The DST proposals do include the possibility of reintroducing a closure type with an owned environment (~Fn
), which would satisfy your need, but it is not clear yet whether that will happen or not.
在实践中,还有其他方法。例如,您可以这样做:
In practice, there are other ways of doing this. For example, you might do this:
pub struct Adder {
n: int,
}
impl Add<int, int> for Adder {
#[inline]
fn add(&self, rhs: &int) -> int {
self.n + *rhs
}
}
fn make_adder(i: int) -> Adder {
Adder {
n: int,
}
}
$ b b
然后,代替 make_adder(3)(4)== 7
,它将是 make_adder(3)+ 4 == 7
或 make_adder(3).add(& 4)== 7
。 (它是添加< int,int>
它正在实现而不只是一个 impl Adder {fn add(& self,other:int ) - > int {self.n + other}
只是为了方便 +
运算符。)
Then, instead of make_adder(3)(4) == 7
, it would be make_adder(3) + 4 == 7
, or make_adder(3).add(&4) == 7
. (That it is Add<int, int>
that it is implementing rather than just an impl Adder { fn add(&self, other: int) -> int { self.n + other }
is merely to allow you the convenience of the +
operator.)
这是一个相当愚蠢的例子,因为 Adder
也可能是 int
在所有的概率,但它有它的可能性。
This is a fairly silly example, as the Adder
might just as well be an int
in all probability, but it has its possibilities.
让我们说,你想返回一个计数器;您可能希望将其作为返回(0,func)
的函数,后一个元素是将返回(1,func)
,& c。但这可以更好地用迭代器建模:
Let us say that you want to return a counter; you might wish to have it as a function which returns (0, func)
, the latter element being a function which will return (1, func)
, &c. But this can be better modelled with an iterator:
use std::num::{Zero, One};
struct Counter<T> {
value: T,
}
impl<T: Add<T, T> + Zero + One + Clone> Counter<T> {
fn new() -> Counter<T> {
Counter { value: Zero::zero() }
}
}
impl<T: Add<T, T> + Zero + One + Clone> Iterator<T> for Counter<T> {
#[inline]
fn next(&mut self) -> Option<T> {
let mut value = self.value.clone();
self.value += One::one();
Some(value)
}
// Optional, just for a modicum of efficiency in some places
#[inline]
fn size_hint(&self) -> (uint, Option<uint>) {
(uint::max_value, None)
}
}
再次,您看到了一个概念,即有一个对象,您可以在该对象上调用一个方法来改变其状态并返回所需的值,而不是创建一个新的可调用对象。这是怎么回事:现在,你可能想调用 object()
,你需要调用 object.method )
。我相信您可以忍受目前存在的那些轻微不便。
Again, you see the notion of having an object upon which you call a method to mutate its state and return the desired value, rather than creating a new callable. And that's how it is: for the moment, where you might like to be able to call object()
, you need to call object.method()
. I'm sure you can live with that minor inconvenience that exists just at present.
这篇关于从函数返回一个闭包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!