Почему я получаю ошибку «использование необъявленного типа или модуля» при вызове функции struct? - PullRequest
0 голосов
/ 25 марта 2019

У меня есть следующий код в 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())
}

Так что именно не такс кодом, который не компилируется?

1 Ответ

1 голос
/ 25 марта 2019

Теперь я не очень хорошо понимаю, почему это не сработает. trt должен представлять копию MyStruct, и тогда он должен иметь свои собственные функции, верно?

Это не совсем так для связанных функций в Rust. С идентификатором trt вы можете вызывать методы , где trt - получатель (self или один из его вариантов, например &self или &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 является идентификатором параметра функции в этом контексте, компилятор на самом деле попытается интерпретировать его как что-то еще (имя модуля, имя типа, ...) после объединения с токеном ::, что приводит к данной ошибке сообщение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...