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/

相关文章:

c - C中的内存消耗

C# : this() mean after a constructor of struct 是什么

generics - 无法将特征边界添加到结构成员

smalltalk - 特征小谈话中的实例变量

c++ - 如何在类(class)结束时获得填充的大小

c - 将不需要的数据保存到错误文件

rust - 在actix线程中进行同步http客户端访存

rust - 在固有实现的上下文中, "nominal type"是什么?

rust - 如何将套接字作为参数传递给在线程中调用的函数?

json - Golang-覆盖嵌入式字段的JSON标签