我将为坐标创建一个通用类型。它应该能够指定每个轴的基数类型。
首先,我的代码如下所示:
use num::Signed;
struct Coordinate<Index: Signed> {
x: Index,
y: Index,
}
另外,我希望它携带额外的绑定信息来帮助我检查实现中的访问,所以我写了这个。
use num::Signed;
struct Coordinate<const Bound: isize, Index: Signed> {
x: Index,
y: Index,
}
但是,即使
Signed
仅针对i8, ..., isize
实现,我也不能简单地将Signed
的值与isize
进行比较。所以我转向这个:
use num::Signed;
struct Coordinate<const Bound: Index, Index: Signed> {
x: Index,
y: Index,
}
当然,失败了。我想知道是否有任何可能的解决方案来解决这个问题。
您的第一个版本正朝着正确的方向发展,它只需要更多的特征界限:
use num::Signed;
#[derive(Debug)]
struct Coordinate<const BOUND: isize, Index>
where
Index: Signed + PartialOrd + NumCast,
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