generics - Why do Rust's operators have the type Output variable? -
this question has answer here:
i've been reading through rust book online , i've reached 4.1, operators , overloading. noticed std::ops::add
defines fn add(self, rhs: rhs) -> self::output;
type output
defined separately in trait.
i understand what's going on here: add
function accepts left hand side self
, , right hand side generic parameter type rhs
.
i want know why output type defined output
alias, instead of being generic (ex. add<rhs, output>
)? convention, or there specific reason it?
while functions operate on variables, can think of traits functions operate on types. when thought of way, type parameters serve inputs function , associated types serve outputs.
since output
associated type, 2 types a
, b
wish impl add
, restricted picking single output
type. output
type parameter, impl add
a
, b
in myriad of ways.
for example, let define mul
trait output
parameter:
trait mul<rhs, output> { fn mul(self, rhs: rhs) -> output; }
now let define complex
type:
#[derive(debug, clone, copy)] struct complex { x: f64, y: f64, } impl complex { fn new(x: f64, y: f64) -> complex { complex { x: x, y: y } } }
we want able multiply f64
:
impl mul<f64, complex> complex { fn mul(self, rhs: f64) -> complex { complex::new(self.x * rhs, self.y * rhs) } }
this works fine. however, come second implementation:
impl mul<f64, f64> complex { fn mul(self, rhs: f64) -> f64 { self.x * rhs } }
when multiply complex
f64
now, ambiguous implementation should called, , type information needed supplied caller. making output
associated type, disallowed. following code throws compiler error conflicting implementations:
impl std::ops::mul<f64> complex { type output = complex; fn mul(self, rhs: f64) -> complex { complex::new(self.x * rhs, self.y * rhs) } } impl std::ops::mul<f64> complex { type output = f64; fn mul(self, rhs: f64) -> complex { self.x * rhs } }
Comments
Post a Comment