There are two pain points I've experienced while using the generic std::num::NonZero
type:
- The type doesn't implement the
Default
trait, forcing you to write customDefault
impl for your structs and enums that otherwise only require a derive impl. - No way to initialize the type without calling unwrap or using an unsafe block, even when the value is known at compile time.
The first problem can be addressed by implementing Default
for all NonZero compatible types and setting the value to 1
. If the value 1
isn't a reasonable default for the signed integers, then Default
should at least be implemented for the unsigned types.
The second problem can be addressed by adding a new declarative macro to the standard library, which let's you initialize the type with a compile-time checked integer literal. The macro definition is extremely simple. Try it out on playground.
Update: as pointed out by @FZs this macro is unsound. See @ogoffart's macro definition instead.
macro_rules! non_zero {
(0) => {
compile_error!("Value cannot be zero")
};
($x: literal) => {
unsafe { std::num::NonZero::new_unchecked($x) }
};
}
Thoughts?