Are you passing an object that implements
Write? As in, why do you need the
Write trait in the function? Its no obvious to me based on what you've shown how its being used.
In general, you only need to specify types that the compiler can't figure out on its own. In the case of your original function, since the type was not used in the arguments or the output, there is no way for the compiler to guess what type you want to use for deserialization.
Typically when you use
Write you are taking as an argument an object that implements
Write. In which case, there's no need to explicitly specify a type, since the object you're passing would be known to the compiler. The signature of the function would be something like this
pub fn count_and_copy<W: std::io::Write, T: serde::de::DeserializeOwned>(
bytes: &[u8], writer: W
) -> Result<usize, Box<dyn std::error::Error>>
You're on the right track with respect to your last question, except that
dyn is indicative of a trait object. I'll refer to text from the rust book that you might find helpful Link
A trait object points to both an instance of a type implementing our specified trait as well as a table used to look up trait methods on that type at runtime. We create a trait object by specifying some sort of pointer, such as a
& reference or a
Box<T> smart pointer, then the
dyn keyword, and then specifying the relevant trait.
We can use trait objects in place of a generic or concrete type. Wherever we use a trait object, Rust’s type system will ensure at compile time that any value used in that context will implement the trait object’s trait. Consequently, we don’t need to know all the possible types at compile time.