你的第一个版本是在正确的方向上,它只需要一些更多的特征界限:
use num::Signed;
#[derive(Debug)]
struct Coordinate<const BOUND: isize, Index>
where
Index: Signed + PartialOrd + Copy,
isize: From<Index>,
{
x: Index,
y: Index,
}
impl<const BOUND: isize, Index> Coordinate<BOUND, Index>
where
Index: Signed + PartialOrd + Copy,
isize: From<Index>,
{
pub fn new(x: Index, y: Index) -> Option<Self> {
if x >= Index::zero()
&& y >= Index::zero()
&& isize::from(x) < BOUND
&& isize::from(y) < BOUND
{
Some(Self { x, y })
} else {
None
}
}
}
fn main() {
dbg!(Coordinate::<10, i16>::new(5, 3));
dbg!(Coordinate::<10, i16>::new(5, 11));
}
[src\main.rs:32] Coordinate::<10, i16>::new(5, 3) = Some(
Coordinate {
x: 5,
y: 3,
},
)
[src\main.rs:33] Coordinate::<10, i16>::new(5, 11) = None
虽然PartialOrd + Copy
看起来很乏味,而且都已经被PrimInt
覆盖了,但我还是会用那个来代替.
此外,您的问题中没有任何内容需要Signed
,所以我会删除它,直到实际需要为止.
use num::PrimInt;
#[derive(Debug)]
struct Coordinate<const BOUND: isize, Index>
where
Index: PrimInt,
isize: From<Index>,
{
x: Index,
y: Index,
}
impl<const BOUND: isize, Index> Coordinate<BOUND, Index>
where
Index: PrimInt,
isize: From<Index>,
{
pub fn new(x: Index, y: Index) -> Option<Self> {
if x >= Index::zero()
&& y >= Index::zero()
&& isize::from(x) < BOUND
&& isize::from(y) < BOUND
{
Some(Self { x, y })
} else {
None
}
}
}
fn main() {
dbg!(Coordinate::<10, i16>::new(5, 3));
dbg!(Coordinate::<10, i16>::new(5, 11));
}
[src\main.rs:32] Coordinate::<10, i16>::new(5, 3) = Some(
Coordinate {
x: 5,
y: 3,
},
)
[src\main.rs:33] Coordinate::<10, i16>::new(5, 11) = None