我有以下类型:
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 }
}
}
现在,这有效:
let monster: CookiesMonster = Monster::new(10);
let dummy = Dummy::new(10);
但这不是:
let monster = CookiesMonster::new(10);
为什么我不能直接在CookiesMonster类型上调用新方法?
答案 0 :(得分:10)
因为这就是特质目前的运作方式。必须在特征上调用特征中的静态方法,而不是在特征的实现者上调用。
答案 1 :(得分:7)
请注意,调用trait而不是实现trait的类型上的方法允许这样的情况明确:考虑是否在示例中添加了以下代码:
trait Newable {
fn new(int) -> Self;
}
impl Newable for CookiesMonster {
fn new(i: int) -> CookiesMonster {
CookiesMonster { cookies: i, hungry_level: 0 }
}
}
在这种情况下,Monster::new
仍然有效,但CookiesMonster::new
会有歧义。
(在这个例子中,它根据类型推断计算了 要使用的特征的实现方式。已经讨论了诸如Trait::<for Type>::static_method
之类的通用语法作为明确记录的方式一个人的意图,但我不确定那是多远。)
2014年7月15日左右更新:“统一函数调用语法”提案跟踪上一段中提到的工作。见Rust RFC PR 132。我的理解是,当CookiesMonster::new
是(1.)提供Monster
方法和(1)的范围内的唯一特征时,RFC中描述的UFCS实际上允许您编写new
。 2.)明确地为CookiesMonster
实施。