Cannot join Vec<String> due to `[String]: Join<_>` not satisfied

Viewed 63

I'm following the example in Ch19 03 Advanced Traits: Using the newtype pattern to implement external traits on external types of The Rust Programming Language.

The example used Vec<String> as the wrapper Type to customize the behaviour of external traits on an external type, and I want to try using Generics here.

Here is my code:

struct VecWrapper<T>(Vec<T>);

impl<String> fmt::Display for VecWrapper<String> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let v = self.0;
        let joined = v.join(",");
        write!(f, "[{}]", joined)
    }
}

But the complier complains:

error[E0599]: the method `join` exists for struct `Vec<String>`, but its trait bounds were not satisfied
   --> src/main.rs:106:24
    |
106 |         let joined = v.join(",");
    |                        ^^^^ method cannot be called on `Vec<String>` due to unsatisfied trait bounds
    |
    = note: the following trait bounds were not satisfied:
            `[String]: Join<_>`

Why this is happening? It' s ok to join Vec<String> if I don' t use Generics, which is illustrated in the example of the book:

struct VecStrWrapper(Vec<String>);

impl fmt::Display for VecStrWrapper {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "[{}]", self.0.join(","))
    }
}

Rust compiler meta:

rustc 1.62.0 (a8314ef7d 2022-06-27)
binary: rustc
commit-hash: a8314ef7d0ec7b75c336af2c9857bfaf43002bfc
commit-date: 2022-06-27
host: x86_64-unknown-linux-gnu
release: 1.62.0
LLVM version: 14.0.5
1 Answers

When implementing a trait for a struct with a specific generic type, you don't need to write it next to impl.

impl fmt::Display for VecWrapper<String> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let v = &self.0;
        let joined = v.join(",");
        write!(f, "[{}]", joined)
    }
}

Also, since you can't move out Vec<T> out of the struct it resides in. In the fmt function you should use a reference instead of a move let v = &self.0;

Related