struct - 实现 Rust 特征会导致找不到结构

标签 struct rust traits

当我在 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 的实现以实现 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 突然不见了?谢谢!

最佳答案

目前,traits 中的关联函数(非方法函数)是通过 trait 调用的,即 SomeTrait::new() .但是,如果你只是这样写,编译器无法计算出你正在使用 哪个 impl,因为没有办法指定 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 技巧。)


旁注:错误消息相当糟糕,但它只是反射(reflect)了这些方法是如何实现的; 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 “模块”存在。

关于struct - 实现 Rust 特征会导致找不到结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25563667/

相关文章:

rust - Rc::clone(&pointer) 如何增加引用计数?

error-handling - 如何处理 rust 上的盒装和链式错误?

closures - 闭包作为函数参数 "cannot infer an appropriate lifetime due to conflicting requirements"

Scala 匿名混入?

c - 函数中的结构和文件中的输出

json - 无法使用带有空格的键名解码 JSON

html - 如何覆盖结构 slice 而不是 slice 结构

swift - 为什么使用结构会增加应用程序的二进制大小?

php - 如何在不冲突的情况下在另一个 PHP Trait 中使用 PHP Trait?

rust - 关联类型的生命周期绑定(bind)被拒绝,尽管它看起来有效