【问题标题】:Why do I get "use of undeclared type or module" error when calling a struct's function?为什么在调用结构的函数时会出现“使用未声明的类型或模块”错误?
【发布时间】:2019-03-25 07:28:25
【问题描述】:

我在 Rust 中有以下代码:

trait MyTrait {
    fn get_value() -> &'static str;
}

#[derive(Debug)]
struct MyStruct;

impl MyTrait for MyStruct {
    fn get_value() -> &'static str {
        "has value"
    }
}


fn main() {
    println!("My value: {}", MyStruct::get_value());
    has_trait(MyStruct);
}

fn has_trait<T>(trt: T) where T: MyTrait + std::fmt::Debug {
    println!("{:?}", trt)
}

这段代码很好。它定义了一个特征和一个结构。该结构实现了特征;这需要实现一个功能。到目前为止一切都很好。但如果我尝试以下代码:

trait MyTrait {
    fn get_value() -> &'static str;
}

#[derive(Debug)]
struct MyStruct;

impl MyTrait for MyStruct {
    fn get_value() -> &'static str {
        "has value"
    }
}


fn main() {
    println!("My value: {}", MyStruct::get_value());
    has_trait(MyStruct);
}

fn has_trait<T>(trt: T) where T: MyTrait + std::fmt::Debug {
    println!("{:?}", trt::get_value())
}

我收到以下错误:

error[E0433]: failed to resolve: use of undeclared type or module `trt`
  --> src/main.rs:21:22
   |
21 |     println!("{:?}", trt::get_value())
   |                      ^^^ use of undeclared type or module `trt`

现在,我不太明白为什么这行不通。 trt 应该代表myStruct 的一个副本,然后它应该有自己的功能,对吧?

有趣的是,以下代码将编译:

trait MyTrait {
    fn get_value(&self) -> &'static str;
}

#[derive(Debug)]
struct MyStruct;

impl MyTrait for MyStruct {
    fn get_value(&self) -> &'static str {
        "has value"
    }
}


fn main() {
    println!("My value: {}", MyStruct.get_value());
    has_trait(MyStruct);
}

fn has_trait<T>(trt: T) where T: MyTrait + std::fmt::Debug {
    println!("{:?}", trt.get_value())
}

那么无法编译的代码到底有什么问题呢?

【问题讨论】:

    标签: rust


    【解决方案1】:

    现在,我不太明白为什么那行不通。 trt 应该代表MyStruct 的一个副本,然后它应该有自己的功能,对吧?

    对于 Rust 中的关联函数,这种方式不太适用。 使用标识符trt,您可以调用方法,其中trt 是接收者(self 或其变体之一,例如&amp;self 或&amp;mut self)。但是,get_value() 没有接收器,所以它是一个关联函数。这类似于某些语言(如 Java)中的 静态方法。与 Java 不同,Rust 中的关联函数只能通过指定该函数的类型或类型参数来调用:

    fn has_trait<T>(trt: T) where T: MyTrait + std::fmt::Debug {
        println!("{:?}", T::get_value())
    }
    

    现在可以工作了,甚至不需要参数trt,因为我们只是调用T 类型的关联函数,而不是方法。 尽管trt 在此上下文中是函数参数的标识符,但编译器实际上会在与:: 标记结合后尝试将其解释为其他内容(模块名称,类型名称,...),因此给出错误消息。

    【讨论】:

    • 谢谢。有用!。但是,T 不代表 Trait。该特征不实现该功能。结构确实(通过函数传递)。试图显示它,它说“预期值,找到类型参数 T”。老实说,我的大脑还是不明白。
    • @OmarAbid Traits 声明事物,而不是实现自己。 MyTrait 实际上声明了关联函数get_value(),这就是为什么它可以从受该特征绑定的类型T 调用。其他错误一定是由于尝试将类型用作值而出现的。
    • 我认为它开始变得有意义了。 T 是 myStruct。但是“trt”不是 myStruct 吗?那么,trt和T有什么区别呢?
    • T 是函数has_trait 的类型参数。当调用此函数时,此T 被单态化为具体类型,在本例中为MyStruct。 trt 是 T 类型的值,因此,当 T 是 MyStruct 时,将是 MyStruct 类型的值。一个是类型,而另一个是实际值。可能值得重温 section 10.2 of the book,其中包含对特征和单态化的更深入解释。
    • @OmarAbid MyStruct 是一个类型。 trt 是一个 value,它的类型恰好是 MyStruct。您可以使用. 运算符对值 调用方法。您可以使用 :: 运算符调用 type 上的关联函数。但是您不能对 type 使用 . 运算符,也不能对 value 使用 :: 运算符。 Rust 中值和类型之间的区别非常明显。有把握是件好事。
    猜你喜欢
    • 1970-01-01
    • 2023-03-29
    • 2019-08-24
    • 2020-06-27
    • 2017-02-18
    • 2021-01-14
    • 1970-01-01
    • 1970-01-01
    • 2017-06-29
    相关资源
    最近更新 更多