Rust 如何安全地初始化'NonZeroU8'类型的常数?
Rust 如何安全地初始化'NonZeroU8'类型的常数?,rust,constants,Rust,Constants,NonZeroU8的构造函数是一个const fn,但它返回一个选项,并且选项。unwrap()不是const fn,因此不会编译以下内容: use std::num::NonZeroU8; const _: NonZeroU8 = NonZeroU8::new(7).unwrap(); 我发现最好的解决办法是: use std::num::NonZeroU8; const _: NonZeroU8 = unsafe {NonZeroU8::new_unchecked(7)}; “不安
NonZeroU8
的构造函数是一个const fn
,但它返回一个选项
,并且选项。unwrap()
不是const fn
,因此不会编译以下内容:
use std::num::NonZeroU8;
const _: NonZeroU8 = NonZeroU8::new(7).unwrap();
我发现最好的解决办法是:
use std::num::NonZeroU8;
const _: NonZeroU8 = unsafe {NonZeroU8::new_unchecked(7)};
“不安全”的使用令人不满意。有安全的方法吗?在
常量中惊慌失措
fns当前不稳定,这就是为什么不能使用展开
。在不使用不安全的的情况下,一个有点难看但稳定的解决方法是使用一些隐含恐慌的东西,例如越界数组索引:
use std::num::NonZeroU8;
const VALUE: NonZeroU8 = match NonZeroU8::new(5) {
Some(v) => v,
None => [][0],
};
fn main() {
println!("Value: {}", VALUE);
}
您可以对此进行测试,并注意将5
更改为0
将导致编译时错误。值得注意的是,在常量中,<代码> NeXun-Chuest仍然会导致零值的编译时错误,所以尽管使用<代码>不安全< /COP>,它是很好的。这使我想起C++中著名的Boost技巧:PIMO,这是最良性的不安全
:只有一个不变量是new\u unchecked
需要的,通过检查是正确的;除了这一行之外,您不需要查看其他任何地方来验证其正确性。因此,我只在这里使用unsafe
(至少在编译器改进允许我们在const
上下文中调用new
)。好的防锈代码会在合理的情况下偶尔使用不安全的;使用笨拙的变通方法来避免不安全
,如果这样做是非常正确的,则不会使代码变得更好。YMMV@trentcl它甚至比这更安全,因为它在const
表达式中使用意味着即使它使用不正确,编译器也会在编译时出错。这就归结为风格偏好,或者我想如果你想让你的代码包含绝对零的不安全的。()