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