[使用 const 初始化编辑]
也可以使用 rust 类型系统计算阶乘。 Crate typenum 允许在类型系统的基础上重新编码二进制算术:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=d34eef48622363ca2096a246cd933554
use std::ops::{ Mul, Sub, };
use typenum::{
B1, Sub1, Prod, U0, U1, U2, U3, U4, U5, U20, U24, Unsigned, Bit, UInt
};
trait Fact {
type F: Unsigned;
}
impl Fact for U0 {
type F = U1;
}
impl<U: Unsigned, B: Bit> Fact for UInt<U, B> where UInt<U, B>: Sub<B1>,
Sub1<UInt<U, B>>: Fact, UInt<U, B> : Mul<<Sub1<UInt<U, B>> as Fact>::F>,
Prod<UInt<U, B>,<Sub1<UInt<U, B>> as Fact>::F>: Unsigned {
type F = Prod<UInt<U, B>,<Sub1<UInt<U, B>> as Fact>::F>;
}
fn main() {
type F0 = <U0 as Fact>::F;
type F1 = <U1 as Fact>::F;
type F2 = <U2 as Fact>::F;
type F3 = <U3 as Fact>::F;
type F4 = <U4 as Fact>::F;
type F5 = <U5 as Fact>::F;
type F20 = <U20 as Fact>::F;
const FACT0: usize = F0::USIZE;
const FACT1: usize = F1::USIZE;
const FACT2: usize = F2::USIZE;
const FACT3: usize = F3::USIZE;
const FACT4: usize = F4::USIZE;
const FACT5: usize = F5::USIZE;
const FACT20: usize = F20::USIZE;
println!("0! = {}", FACT0);
println!("1! = {}", FACT1);
println!("2! = {}", FACT2);
println!("3! = {}", FACT3);
println!("4! = {}", FACT4);
println!("5! = {}", FACT5);
println!("20! = {}\n", FACT20);
println!("Binary structure:");
println!("F4 = {:?}",F4::new());
println!("U24 = {:?}\n",U24::new());
fn print_u24(_: U24) {
println!("type F4 is the same as type U24");
}
print_u24(F4::new());
}
导致:
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
20! = 2432902008176640000
Binary structure:
F4 = UInt { msb: UInt { msb: UInt { msb: UInt { msb: UInt { msb: UTerm, lsb: B1 }, lsb: B1 }, lsb: B0 }, lsb: B0 }, lsb: B0 }
U24 = UInt { msb: UInt { msb: UInt { msb: UInt { msb: UInt { msb: UTerm, lsb: B1 }, lsb: B1 }, lsb: B0 }, lsb: B0 }, lsb: B0 }
type F4 is the same as type U24
阶乘类型 F0, F1, F2, F3 F4 F5, F20 当然是在编译时生成的。
然后使用与 trait Unsigned 关联的常量 USIZE 来初始化 usize 常量,FACT0, FACT1, ...
嗯,这当然不是在编译时计算阶乘的最有效方法; const fn 更好!然而,有趣的是,rust 类型系统足够强大,可以在编译时实现一些函数式和递归计算!
这可能对其他任务有用。例如,当您必须处理一些算术运算时(至少现在是这样),它也是 const 泛型的一个有趣的替代方案。通常,这种类型机制用于泛型数组或代数中。