Reputation: 15976
I have the following code in 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)
}
This code is fine. It defines a trait and a struct. The struct implements the trait; which requires to implement a function. Everything is fine until now. But if I try the following code:
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())
}
I get the following error:
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`
Now, I don't really understand very well why that wouldn't work. trt
should represent a copy of myStruct
and then it should have its own functions, right?
Interestingly, this following code will compile:
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())
}
So what is exactly wrong with the code that doesn't compile?
Upvotes: 2
Views: 4694
Reputation: 29972
Now, I don't really understand very well why that wouldn't work.
trt
should represent a copy ofMyStruct
and then it should have its own functions, right?
It doesn't quite work that way for associated functions in Rust.
With the identifier trt
, you can call methods where trt
is the receiver (self
or one of its variations such as &self
or &mut self
). However, get_value()
does not have a receiver, so it is an associated function. This resembles a static method in some languages such as Java. Unlike Java, associated functions in Rust can only be called by specifying the type or type parameter with that function:
fn has_trait<T>(trt: T) where T: MyTrait + std::fmt::Debug {
println!("{:?}", T::get_value())
}
This will now work, and would not even need the parameter trt
, because we're just calling an associated function of the type T
, rather than a method.
Although trt
is an identifier to a function parameter in this context, the compiler will actually try to interpret it as something else (module name, type name, ...) once combined with the ::
token, hence the given error message.
Upvotes: 1