当我在Rust中的结构上实现特征时,它导致找不到结构类型。首先,工作代码:
trait SomeTrait {
fn new() -> Box<SomeTrait>;
fn get_some_value(&self) -> int;
}
struct SomeStruct {
value: int
}
impl SomeStruct {
fn new() -> Box<SomeStruct> {
return box SomeStruct { value: 3 };
}
fn get_some_value(&self) -> int {
return self.value;
}
}
fn main() {
let obj = SomeStruct::new();
println!("{}", obj.get_some_value());
}
这里没有使用SomeTrait特征。一切正常。如果我现在改变SomeStruct的impl来实现SomeTrait:
trait SomeTrait {
fn new() -> Box<SomeTrait>;
fn get_some_value(&self) -> int;
}
struct SomeStruct {
value: int
}
impl SomeTrait for SomeStruct {
fn new() -> Box<SomeTrait> {
return box SomeStruct { value: 3 };
}
fn get_some_value(&self) -> int {
return self.value;
}
}
fn main() {
let obj = SomeStruct::new();
println!("{}", obj.get_some_value());
}
我收到错误:
trait.rs:21:13: 21:28 error: failed to resolve. Use of undeclared module `SomeStruct`
trait.rs:21 let obj = SomeStruct::new();
^~~~~~~~~~~~~~~
trait.rs:21:13: 21:28 error: unresolved name `SomeStruct::new`.
trait.rs:21 let obj = SomeStruct::new();
我做错了什么?为什么SomeStruct突然失踪?谢谢!
答案 0 :(得分:1)
目前,通过特征调用特征中的相关函数(非方法函数),即SomeTrait::new()
。但是,如果你只是写这个,那么编译器就无法解决你正在使用的 ,因为没有办法指定SomeStruct
信息(它只能起作用)如果签名中某处提到了特殊的Self
类型。也就是说,编译器需要能够确定应该调用哪个版本的new
。 (这是必需的;它们可能有非常不同的行为:
struct Foo;
impl SomeTrait for Foo {
fn new() -> Box<SomeTrait> { box Foo as Box<SomeTrait> }
}
struct Bar;
impl SomeTrait for Bar {
fn new() -> Box<SomeTrait> {
println!("hello")
box Bar as Box<SomeTrait>
}
}
或者比印刷更具戏剧性的东西。)
这是一个由UFCS填充的语言空洞。目前,您需要使用虚拟 - Self
技巧:
trait SomeTrait {
fn new(_dummy: Option<Self>) -> Box<SomeTrait>;
...
}
然后被称为SomeTrait::new(None::<SomeStruct>)
。
但是,我怀疑为什么要从构造函数返回一个盒装对象。这通常不是一个好主意,通常直接返回普通类型会更好,并且用户可以在必要时将其打包,即
trait SomeTrait {
fn new() -> Self;
...
}
(注意:此签名提及Self
,因此上面的Option
诀窍并非必需。)
旁注:错误信息相当糟糕,但它只反映了这些方法的实现方式; impl Foo
中的关联函数与编写mod Foo { fn ... }
非常相似。您可以通过强制编译器创建该模块来看到它的不同之处:
struct Foo;
impl Foo {
fn bar() {}
}
fn main() {
Foo::baz();
}
仅打印
<anon>:7:5: 7:13 error: unresolved name `Foo::baz`.
<anon>:7 Foo::baz();
^~~~~~~~
即。 Foo
&#34;模块&#34;存在。