Mut*_*pus 9 generics operator-overloading rust
我一直在线阅读Rust书,我已经达到4.1,操作员和重载.我注意到,std::ops::Add将其定义为fn add(self, rhs: RHS) -> Self::Output;具有type Output在该性状分别定义的.
我理解这里发生了什么:add函数接受左侧作为self,右侧接受通用参数类型RHS.
我想知道为什么用Output别名定义输出类型,而不是另一个泛型(例如Add<RHS, Output>)?它只是一个惯例,还是有特定的理由?
pah*_*olg 10
当函数对变量进行操作时,您可以将特征视为对类型进行操作的函数.当想到这种方式时,类型参数用作函数的输入,相关类型用作输出.
由于Output是关联的类型,两种类型的A和B我们希望impl Add,我们仅限于采摘单一Output类型.是Output一个类型参数,我们可以impl Add为A和B在无数种方法.
例如,让我们定义一个Mul特征,其中Output是一个参数:
trait Mul<RHS, Output> {
fn mul(self, rhs: RHS) -> Output;
}
Run Code Online (Sandbox Code Playgroud)
现在让我们定义一个Complex类型:
#[derive(Debug, Clone, Copy)]
struct Complex {
x: f64,
y: f64,
}
impl Complex {
fn new(x: f64, y: f64) -> Complex {
Complex { x: x, y: y }
}
}
Run Code Online (Sandbox Code Playgroud)
我们希望能够乘以f64:
impl Mul<f64, Complex> for Complex {
fn mul(self, rhs: f64) -> Complex {
Complex::new(self.x * rhs, self.y * rhs)
}
}
Run Code Online (Sandbox Code Playgroud)
一切正常.但是,我们可以提出第二个实现:
impl Mul<f64, f64> for Complex {
fn mul(self, rhs: f64) -> f64 {
self.x * rhs
}
}
Run Code Online (Sandbox Code Playgroud)
当我们将a乘以a时Complex,f64应该调用哪个实现是不明确的,并且调用者需要提供额外的类型信息.通过创建Output关联类型,这是不允许的.以下代码会针对冲突实现引发编译器错误:
impl std::ops::Mul<f64> for Complex {
type Output = Complex;
fn mul(self, rhs: f64) -> Complex {
Complex::new(self.x * rhs, self.y * rhs)
}
}
impl std::ops::Mul<f64> for Complex {
type Output = f64;
fn mul(self, rhs: f64) -> Complex {
self.x * rhs
}
}
Run Code Online (Sandbox Code Playgroud)
这是关于谁可以指定输出类型。一般来说,当您将两种类型相乘时,例如f64乘以f64,很清楚结果的类型应该是什么:f64。对于调用者来说,请求结果类型是没有意义的String- 因此它作为输入实际上没有意义。
我可以想象在某些情况下,您可能希望选择不同的输出,但它们有点小众(比如u32*u32返回完整u64结果?);另外,如果有多个选项,您如何指定您想要哪一个?虽然您可以编写Add<u32, u64>::add(a, b),但它会使简单的表达式(如a*b*c歧义)变得模糊,并使类型推断变得更加困难!
| 归档时间: |
|
| 查看次数: |
1620 次 |
| 最近记录: |