5

I'm reading the book Programming Rust, and learned about Rust's traits and generic types. And I find that type bounds can be placed on the methods of a trait. Then I constructed the following trait and implemented it for a struct.

use std::fmt::Display;
trait Test<T> {
    fn show(&self)
    where
        T: Display;
    fn test(&self);
}

struct S<T> {
    field: T,
}

impl<T> Test<T> for S<T> {
    fn show(&self)
    where
        T: Display,
    {
        println!("My field: {}", self.field);
    }

    fn test(&self) {
        println!("Just for test");
    }
}

The following code does not compile, just as expected:

struct R;

fn main() {
    let s = S { field: R {} };
    s.show();
}

But the following code does compile and run:

struct R;

fn main() {
    let s = S { field: R {} };
    s.test();
}

Shouldn't Rust just reject the code when s is defined as S { field: R{} }? Does it mean that s is an instance of S that implements trait T partially?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
shengjiew
  • 51
  • 1
  • 3

1 Answers1

1

Can Rust traits be partially implemented?

No. Either all in, or nothing.

But why is one code compiling but the other won't.

The reason is the extra bound on show

fn show(&self) where T: Display;

This means, that when you want to call this method, your T must implement Display. If it's not implemented, you can't call it.

Rusts "generics" work different than C++ for example.

In C++ you have SFINAE (Substitution failure is not an error). This is kind of duck typing.
Rust works on bounds, that means you have to specify what kind of traits a your "generic" must impelement to use the functions. In this case you can call Display::fmt because you specified, that your T must implement that trait.

This bound is not specified for your test method and therefore you can call it with whatever type you want.

hellow
  • 12,430
  • 7
  • 56
  • 79
  • It's known that implementing a trait means implementing all its methods. So implementing trait `Test` for `S`, it means both of `test` and `show` are implemented. Why rust accepts an `S` that does not conform all the type bound requirements exposed by `Test`'s methods. – shengjiew Apr 26 '19 at 06:37
  • @shengjiew Correct it has implementation of `show` , otherwise compiler would give an error like `show` method not found for `s`, imo the behavior is not different than [this](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=fb2c9c936c8c13d1c88cac67d752a347), function is there but you cannot use for that type. – Ömer Erden Apr 26 '19 at 07:02