Mai*_*tor 3 functional-programming rust
假设我在 Rust 中有以下类型:
type UnOp = fn(u64) -> u64;
Run Code Online (Sandbox Code Playgroud)
该类型允许我创建不同的一元运算:
const add1 : UnOp = |x| x + 1;
const mul2 : UnOp = |x| x * 2;
Run Code Online (Sandbox Code Playgroud)
现在,假设我需要在代码的不同位置使用add2, add3, (...), 来表示不同的数字。add4编写所有定义会很麻烦,因此,我编写了一个通用adder函数:
fn adder(add : u64) -> UnOp {
|x| x + add
}
Run Code Online (Sandbox Code Playgroud)
这将允许我为任何数字写add(2)、add(3)等:
// Prints 2 + 40
println!("result is: {}", adder(2)(40))
Run Code Online (Sandbox Code Playgroud)
问题是:adder实际上不是有效的 Rust 代码,因为它|x| ...是一个闭包,而不是静态函数。为了按照adder我想要的方式工作,我需要修改UnOp为闭包:
type UnOp = Box<dyn Fn(u64) -> u64>;
fn adder(add : u64) -> UnOp {
Box::new(move |x| x + add)
}
Run Code Online (Sandbox Code Playgroud)
问题是:如果我知道 的每个用法都adder(N)应用于静态值怎么办?
在这种情况下,创建动态闭包在计算方面将是浪费的。不仅如此,使Box<dyn ...>代码变得非常复杂,甚至可能需要生命周期注释。我的问题是:
是否可以adder在不修改 的原始定义的情况下创建UnOp?也就是说,letUnOp是一个静态函数,而不是一个闭包?
从逻辑上讲,没有理由不可能,只要 的参数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);
}
Run Code Online (Sandbox Code Playgroud)
这会引发 2 个错误:
- the type of const parameters must not depend on other generic parameters
- using function pointers as const generic parameters is forbidden
Run Code Online (Sandbox Code Playgroud)
您可以使用以下方法来完成const Generics:
type UnOp = fn(u64) -> u64;
const fn adder<const ADD: u64>(x: u64) -> u64 {
ADD + x
}
fn main() {
let add_1: UnOp = adder::<1>;
println!("{}", add_1(1));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
582 次 |
| 最近记录: |