我如何添加常量泛型?假设我有一个foo类型:
pub struct foo {
value: f64,
}我想实现mul,这样我就可以将2相乘。foo在一起。我想请客bar作为维度,因此
foo{value: x} * foo{value: k} == foo{value: x * k}
详情如下:
impl Mul> for foo {
type Output = foo<{baz + quux}>;
fn mul(self, rhs: foo) -> Self::Output {
Self::Output {
value: self.value * rhs.value,
}
}
}我收到一个错误,告诉我需要添加一个where边界
{baz+quux}在输出类型的定义内。这到底是什么意思,我该如何实现它?我找不到任何看似相关的信息where
发布于 2021-02-25 12:49:35
解决方案
我得到了你代码的一个变种here
impl Mul> for Foo
where Foo<{baz + quux}>: Sized {
type Output = Foo<{baz + quux}>;
fn mul(self, rhs: Foo) -> Self::Output {
Self::Output {
value: self.value * rhs.value,
}
}
}我是怎么做到的我已经重现了您得到的完整错误,但没有添加where
下面的子句:
error: unconstrained generic constant
--> src/main.rs:11:5
|
11 | type Output = Foo<{baz + quux}>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: try adding a `where` bound using this expression: `where [u8; {baz + quux}]: Sized`现在,它建议的子句不是很有用,原因之一是:静态大小的片的长度参数必须是usize,但我们的价值观baz和quux(和它们的总和)是i64。我可以想象编译器的作者会包含这个特殊的建议,因为常量泛型的主要用例是在类型中嵌入数组大小。我已经在GitHub上打开了一个问题
关于这个诊断。
为什么这是必要的?
Awhere子句根据一个或多个泛型参数或其派生参数必须满足的特征和生存期指定对某些泛型代码元素的约束-函数、类型、特征,或者在这种情况下,实现。对于许多情况,都有等效的简写,但总体要求是完全指定约束。
在我们的例子中,表面上看,这个实现适用于baz和quux,但由于整数溢出,情况并非如此;如果我们为两者提供足够大的具有相同符号的值,则它们的和不能由i64
。这意味着i64未在加法下关闭。我们添加的约束要求两个值的和在i64,间接地,通过要求使用它的类型的东西。因此,为两者提供2^31baz和quux是无效的,因为结果类型
Foo<{baz + quux}>不存在,因此它不可能实现Sized特征。虽然从技术上讲,这是一个比我们需要的更严格的约束(Sized是比简单存在的类型更强的需求),所有Foo哪些现有的实现Sized,因此在我们的情况下是相同的。另一方面,在没有约束的情况下,没有where子句,显式或速记,指定此约束。
https://stackoverflow.com/questions/66361365
复制相似问题