Rust ships with non-zero integer types now, which let programmers promise (memory-savingly!) that a number can never be zero. That's great, but sadly the standard library has not got a whole lot of tools to help you use them ergonomically.
Creating and handling constant literals is neat, but the standard
library (and the rust parser at the moment) have no affordances to
easily create values of num::NonZeroU*
types from constant
literals. This crate ships a nonzero!
macro that lets you write
nonzero!(20u32)
, which checks at compile time that the constant
being converted is non-zero, instead of the cumbersome (and
runtime-checked!) NonZeroU32::new(20).unwrap()
.
The stdlib num::NonZeroU*
types do not implement any common
traits (and neither do their zeroable equivalents). Where this
lack of traits in the standard library becomes problematic is if
you want to write a function that takes a vector of integers, and
that returns a vector of the corresponding non-zero integer types,
minus any elements that were zero in the original. You can write
that with the standard library quite easily for concrete types:
rust
fn only_nonzeros(v: Vec<u8>) -> Vec<NonZeroU8>
{
v.into_iter()
.filter_map(|n| NonZeroU8::new(n))
.collect::<Vec<NonZeroU8>>()
}
let expected: Vec<NonZeroU8> = vec![nonzero!(20u8), nonzero!(5u8)];
assert_eq!(expected, only_nonzeros(vec![0, 20, 5]));
But what if you want to allow this function to work with any integer type that has a corresponding non-zero type? This crate can help:
```rust
fn onlynonzeros(v: Vec) -> Vec
// It works for u8
:
let inputu8: Vec
// And it works for u32
:
let inputu32: Vec
License: Apache-2.0