假设我在Rust中有以下类型:
那种类型允许我创建不同的一元操作:
这将允许我编写
问题是:
问题是:如果我知道每个
在这种情况下,创建动态闭包会在计算方面浪费资源。不仅如此,
是否有可能创建
从逻辑上讲,没有理由不可能,只要
编辑:附加细节
@Netwave 的回答提出了一个很好的解决方案,针对我给出的具体示例解决了这个问题。但遗憾的是,如果
type UnOp = fn(u64) -> u64;
那种类型允许我创建不同的一元操作:
const add1 : UnOp = |x| x + 1;
const mul2 : UnOp = |x| x * 2;
假设我需要在代码不同位置,对不同的数字进行 add2
、add3
、add4
(...)等操作。写下所有定义会很繁琐,因此我写了一个通用的 adder
函数:
fn adder(add : u64) -> UnOp {
|x| x + add
}
这将允许我编写
add(2)
, add(3)
等任何数字的代码:// Prints 2 + 40
println!("result is: {}", adder(2)(40))
问题是:
adder
实际上不是有效的 Rust 代码,因为 |x| ...
是一个闭包,而不是静态函数。要使 adder
按我希望的方式工作,需要将 UnOp
修改为闭包形式:type UnOp = Box<dyn Fn(u64) -> u64>;
fn adder(add : u64) -> UnOp {
Box::new(move |x| x + add)
}
问题是:如果我知道每个
adder(N)
的使用都应用于静态值,怎么办?在这种情况下,创建动态闭包会在计算方面浪费资源。不仅如此,
Box<dyn ...>
会极大地复杂化代码,并且甚至可能需要生命周期注释。我的问题是:是否有可能创建
adder
而不修改UnOp
的原始定义?也就是让UnOp
成为一个静态函数,而不是闭包?从逻辑上讲,没有理由不可能,只要
adder
的参数是静态的,Rust 应该能够在编译时将其展开,生成每个特定实例。
编辑:附加细节
@Netwave 的回答提出了一个很好的解决方案,针对我给出的具体示例解决了这个问题。但遗憾的是,如果
UnOp
是多态的,或者常量参数本身是一个函数,则无法解决这个问题。type UnOp<A> = fn(A) -> A;
pub fn adder<const ADD: u64>() -> UnOp<u64> {
|x| ADD + x
}
pub fn apply<A, const op : UnOp<A>, const x : A>() -> A {
return op(x);
}
这引发了2个错误:
- the type of const parameters must not depend on other generic parameters
- using function pointers as const generic parameters is forbidden
UnOp
是多态的,或者const参数是一个函数,它就不起作用。我已经编辑了问题,展示了这个解决方案不起作用的例子。我想知道是否有一种方法可以规避这个限制?无论如何,你的答案是非常准确的,尽管它没有涵盖我的实际情况。 - MaiaVictor