从Rust中涉及泛型的特征方法返回一个闭包

时间:2016-04-04 23:23:09

标签: lambda functional-programming rust

我正在学习Rust并且遇到了涉及闭包的棘手问题。我已经有了很多基本的闭包示例,但是现在我已经走出了基本的“make adder”和“call on”示例,事情变得越来越混乱。这是我的代码的第一部分,它起作用:

trait TransformationElt<T, F> where F: Fn(T) -> T {
    fn get_transform(&self) -> Box<F>;
}

pub struct AddSome { pub x: i64 }

impl AddSome  {
    fn the_transform(&self) -> Box<Fn(i64) -> i64> {
        Box::new(|x: i64| x + 1 as i64)
    }
}

这成功返回一个堆分配的闭包,它增加1,实现我们的AddSome类型。我希望AddSome实施TransformationElt,特别是类型i64

impl<F: Fn(i64) -> i64> TransformationElt<i64, F> for AddSome  {
    fn get_transform(&self) -> Box<F> {
        Box::new(move |x: i64| x + self.x as i64)
    }
}

经过多次hackery和尝试不同的事情,我仍然无法编译。我通常得到的错误是:

  

src / lex / math / algebra / groups.rs:31:16:31:46错误:不匹配的类型:    预期F,      找到[closure@src/lex/math/algebra/groups.rs:31:16: 31:46 self:_]   (预期的类型参数,       发现关闭)[E0308]

如何解决这个看似基本的问题并实现我的“转换”类型?

最后一件事 - 我有理由想把事情当作封闭。我打算把它们等等组合起来,我确实需要高阶函数。

1 个答案:

答案 0 :(得分:2)

编译器正在阻止你,因为你试图欺骗它。当我们撒谎时,通过我们的程序员来看是非常好的。

你是怎么说谎的?你说“我要编写一个采用任意类型的方法(有一些限制),然后我将返回一个只包含该类型的方框”。然后你继续返回一个传入值的框;你插入了包装器垃圾,就编译器而言。

下面是一个小例子:

fn wrapper<F>(f: F) -> Box<F>
    where F: Fn(u8) -> u8
{
    Box::new(|x| f(x) + 1)
}

fn main() {}

你真正想说的是你将返回一些实现特征的东西,但是没有描述如何(因为你不能指定一个闭包)。你可以使用间接,一个盒装的特征对象:

fn wrapper<F>(f: F) -> Box<Fn(u8) -> u8>
    where F: Fn(u8) -> u8 + 'static
{
    Box::new(move |x| f(x) + 1)
}

fn main() {}

高度相关:

  1. Return a closure from a function
  2. Returning a closure from a function
  3. Figuring out return type of closure