etchesketch
etchesketch

Reputation: 873

Why does the Rust standard library implement traits for both Thing and &Thing?

I was reading the question The trait `std::fmt::Write` is not implemented for `Stdout` when it should be where the asker noted that the rust documentation shows that the std::io::Write trait is implemented for both &Stdout and Stdout.

I don't understand why this is necessary or how you would use it. Isn't everything you define for Thing always implemented for &Thing? Why would you implement something for &Thing without implementing it for it's definition?

Upvotes: 5

Views: 347

Answers (2)

Coder-256
Coder-256

Reputation: 5618

Building on @Silvio-Mayolo's answer: in this particular case, there was originally just an implementation for Stdout; and the more-flexible implementation for &Stdout was added later, which provides a strict superset of functionality, notably allowing you to share the reference between threads. The original implementation can't be removed without breaking backwards compatibility with existing code using the by-value implementation (auto-deref isn't perfect, you would still need to go back and add an & in some situations).

Upvotes: 1

Silvio Mayolo
Silvio Mayolo

Reputation: 70297

Isn't everything you define for Thing always implemented for &Thing?

No, an implementation for a type T will not automatically implement anything for &T. Now, sometimes blanket implementations can kick in, and if you pass a &&T to a function expecting a &T, then Rust will insert dereferences for you, but that does not mean the trait was implemented for &T, just that Rust helped you out a bit.

Why would you implement something for &Thing without implementing it for it's definition?

There's a very good example of that which we use all the time: String::from.

impl From<&str> for String {
  fn from(value: &str) -> String {
    ...
  }
}

From::<T>::from takes an argument, by value. No references or anything, just straight-up a value of type T. So we can never write a From<str> implementation for anything, since str is unsized and hence cannot be a function argument on its own. But it makes perfect sense to convert a &str to a String: that's just making an owned copy of the string.

Upvotes: 2

Related Questions