RUSTDOCS给出了以下毯式实现的示例
impl<T: Display> ToString for T {
// --snip--
}
我更复杂的特性不允许我编写一个全面的实现。
/// a fixed size 2D array (WxH) that can be indexed by [usize;2]
pub trait Grid<C: Copy + Eq, const W: usize, const H: usize>:
IndexMut<[usize; 2], Output = Option<C>>
{
}
// allow to transform one grid implementation into another
// as long as they contain the same elements and have the same size
impl<C, O, I, const W: usize, const H: usize> From<I> for O
where
O: Default + Grid<C, W, H>,
I: Grid<C, W, H>,
C: Copy
{
fn from(input: O) -> O {
let mut output = O::default();
for i in 0..O::W {
for j in 0..O::H {
output[[i, j]] = input[[i, j]];
}
}
output
}
}
错误说
the type parameter `C` is not constrained by the impl trait, self type, or predicates
the const parameter `W` is not constrained by the impl trait, self type, or predicates
expressions using a const parameter must map each value to a distinct output value
proving the result of expressions other than the parameter are unique is not supported
感觉它是通过O: Grid<Player, W, H>
约束的,但这似乎不是正确的约束。
围绕const泛型参数的错误是次要的(转移注意力?)。当我用常量替换它们时,围绕C(元素类型)的错误仍然存在。
1条答案
按热度按时间t98cgbkg1#
问题是,对于编译器来说,变量
C
、W
和H
可能有多个值,考虑一下如果I
实现Grid<Foo, 1, 2>
* 和 *Grid<Foo, 500, 50>
会发生什么:您的blanketFrom
实现应该使用哪个Grid
实现是不明确的。(对于给定的O
或I
,C
实际上不能有多个值,但编译器实际上并没有推理出这一点。)这个问题的解决方案是将trait的 * generic * 改为 associated types(和associated constants),这意味着trait不能为同一个self类型实现多次:
但是,由于以下几个原因,这仍然无法编译:
From
impl,因为它可能会与满足不同边界的任意两个类型的 * 某个其他crate的 *From
impl重叠--而且它总是与标准库中的blanketFrom<T> for T
重叠。一般来说,只能实现
From<TypeYouDefined> for T
或From<T> for TypeYouDefined
--而不是完全通用的、笼统的From
实现。