从函数返回一个闭包 [英] Return a closure from a function

查看:120
本文介绍了从函数返回一个闭包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


请注意,此问题与发布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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆