Generics 一般情况下,将不同类型的值相乘
假设我想写一个泛型函数,它接受某个Generics 一般情况下,将不同类型的值相乘,generics,rust,traits,Generics,Rust,Traits,假设我想写一个泛型函数,它接受某个K类型的值,并用一个f64交换相乘。以下工作: fn generic1(a:K,b:f64)->K 哪里 K:Mul+添加+复制, f64:Mul, { a*b+b*a } 但是,我现在不再能够在同一个函数中乘以两个浮点数。实际上,似乎绑定的f64:Mul正在覆盖/隐藏(?)用于f64的implimpl-Mul。以下是一个例子: fn generic2(a:K,b:f64)->K 哪里 K:Mul+Add+Add+Copy, f64:Mul, { a*b+b*
K
类型的值,并用一个f64
交换相乘。以下工作:
fn generic1(a:K,b:f64)->K
哪里
K:Mul+添加+复制,
f64:Mul,
{
a*b+b*a
}
但是,我现在不再能够在同一个函数中乘以两个浮点数。实际上,似乎绑定的f64:Mul
正在覆盖/隐藏(?)用于f64的implimpl-Mul。以下是一个例子:
fn generic2(a:K,b:f64)->K
哪里
K:Mul+Add+Add+Copy,
f64:Mul,
{
a*b+b*a+b*b
}
这将导致以下编译器错误:
|
16 | a * b + b * a + b * b
| ^ expected type parameter, found f64
|
= note: expected type `K`
found type `f64`
(),即f64*
现在仅适用于
类型为K
的情况
作为一种解决方法,我可以使用完全限定的语法::mul(b,b)
,但这非常难看。感觉编译器应该能够看到它可以使用类型为f64
的输出,因此使用f64*f64
的实现,而不是f64*K
对于我想做的事情,有一个不太抽象的例子:K
可以是向量类型,也可以是标量类型,我希望能够用它以一种通用的方式进行交换标量乘法
这是怎么回事?为什么我不能再乘b*b
更新:@Ömer erden注意到,当显式指定f64:Mul时,它也可以工作。不幸的是,在导入时,解决方法会中断-请参阅
我不确定alga做了什么来打破这种已经很奇怪的行为。正如Ömer已经指出的那样,这看起来更像是类型检查器的一个缺陷或限制,而不是alga中的一个缺陷,因为理想情况下,对于任何内置类型,没有代码能够破坏impl Mul
或类似的分辨率。这是一个约束,它告诉我们当K
是正确的操作数时,您可以将f64
与K
相乘,输出为K
。还告诉f64
必须实现Mul
f64:Mul,
我还不知道,这可能是因为类型检查器或bug的功能有限,但由于约束条件Mul
,在f64
上实现Mul
变得模棱两可
如果在您的案例中明确说明了Mul
的预期行为:
fn generic2(a:K,b:f64)->K
哪里
K:Mul+Add+Add+Copy,
f64:Mul+Mul,
{
a*b+b*a+b*b
}
它将按预期工作
这相当令人惊讶。我的意思是,f64
是一个具体类型,因此编译器知道它的特性。我们仍然可以使用Mul:::Mul(b,b)
调用标准乘法,因此编译器仍然知道这是可能的。它不再是一个选项。@SvenMarnach你是对的,这应该约束K
而不是f64
,更新帖子以避免误导它与alga
无关,它的发生是因为num_complex
,这是alga
的一个依赖项,请看这个,我想,这个实现再次让事情变得模棱两可(f64正在应用这个宏),下面是我在没有板条箱的情况下复制的行为: