I have the following types:
trait Monster {
fn attack(&self);
fn new(int) -> Self;
}
struct CookiesMonster {
cookies: int,
hungry_level: int,
}
impl Monster for CookiesMonster {
fn new(i: int) -> CookiesMonster {
CookiesMonster { cookies: i, hungry_level: i + 1 }
}
fn attack(&self) {
println!("I have {:d} cookies!!", self.cookies)
}
}
struct Dummy {
count: int
}
impl Dummy {
fn new(i: int) -> Dummy {
Dummy { count: i }
}
}
Now, this works:
let monster: CookiesMonster = Monster::new(10);
let dummy = Dummy::new(10);
But this doesn't:
let monster = CookiesMonster::new(10);
Why can't I call the new method directly on the CookiesMonster type?
Because that's how traits work at the moment. Static methods in traits must be called on the trait, and not on the implementor of the trait.
Note that calling the methods on the trait instead of on the type implementing the trait allows cases like this to be unambiguous: Consider if you added the following code to your example:
trait Newable {
fn new(int) -> Self;
}
impl Newable for CookiesMonster {
fn new(i: int) -> CookiesMonster {
CookiesMonster { cookies: i, hungry_level: 0 }
}
}
In this context, Monster::new
still works, but CookiesMonster::new
would be ambiguous.
(In this example, it figures how which implementation of the trait to use based on type inference. A generalized syntax such as Trait::<for Type>::static_method
has been discussed as a way to explicitly write down one's intentions, but I am not sure how far along that is.)
Update circa 15 July 2014: the "Unified Function Call Syntax" proposal tracks the work alluded to in the previous paragraph. See Rust RFC PR 132. My understanding is that UFCS as described in that RFC would actually allow for you to write CookiesMonster::new
when Monster
is the only trait in scope that both (1.) provides the new
method and (2.) is unambiguously implemented for CookiesMonster
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With