我正在学习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]
如何解决这个看似基本的问题并实现我的“转换”类型?
最后一件事 - 我有理由想把事情当作封闭。我打算把它们等等组合起来,我确实需要高阶函数。
答案 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() {}
高度相关: