On my own, I've basically learned the 101, and 201 sections of this talk. Even some of the 301 section I knew, like how Trait Objects are represented, she doesn't go into the vtables. I always saw Trait Objects as runtime polymorphism, with traits as compile time polymorphism, both forms through composition rather than inheritance. What didn't dawn on me, was the possibility to operate over heterogeneous collections by boxing Trait Objects. That is really cool, and a perfectly example of when to use heap allocation. I like how in Rust you can make these high-level trade-offs that are impossible in most languages.
I agree! I knew it was *possible* to do stuff like the heterogeneous collections w/ vectors of boxed types, but it hadn’t really dawned on me as a common use case.
Just for the record, Box is not the only way to get Trait Objects and heterogeneous collections. Any kind of (fat) pointer / reference suffices: Box but also &Trait, as well as Rc etc. And nowadays it is preferred to prefix a Trait name with the 'dyn' keyword to better disambiguate between the trait itself (which is NOT a type) and the dynamic trait object type: Box, &dyn Trait
This was indeed a great lecture and she is a great teacher. I wrote everything down while watching the video (easier to follow and understand, especially in 301). In case someone wants to try the "source code", it can be found here: github.com/lightern/rust/blob/master/DD.rs
I don't get it. How does a typical OO background make traits hard to understand? Also, for a "deep dive", this doesn't dive very deep. I was hoping to learn the differences between using generics on a trait and having a type field.
I think I'm missing the point here. What I took away from this talk is that I can replace a primitive or a Vec with a Trait for no reason. I feel like I understood traits better before I watched this, but everyone else is saying this talk was great. I realize she chose simple examples on purpose, but these are cases where traits shouldn't be used.
I think she is a great speaker as well. The only thing that I missed was how the call was implemented behind the scenes. How does the program know which method to call on which "abstract" Cast?
Basically, a trait object consists of two pointers (effectively, a "fat pointer"). One part points to the struct memory, the other part points to the impl of the trait for that struct.
dyn wasn't in Rust when the presentation was made, it was introduced later to create trait objects. in earlier versions using a trait in the place of a type would implicitly mean a trait object (impl Trait didn't exist then either)
Thank you for this video. It cleared up for me a number of questions I had about Traits -- which are a little like Java's interfaces, but far more powerful. I won't even mention Java! :D
I know rust's OO has its unique. But from what described here, I don't see difference compare to C++ or Java. Anybody can make it more explicit, what's the difference.
There really isn't one. Traits are basically just interfaces. The difference is mostly historical. Rust uses them by default, consistently, everywhere (especially the standard library) and for every thing, since it started. Unlike in C++ or Java, they weren't added as an optional patch to the (retrospectively obvious) disaster that is the traditional inheritance model. The general theme in Rust is that it doesn't really contain anything new. It just has the hindsight of what worked and didn't work in C, C++, Haskel and others and has benefit of fresh start. A lot of stuff that became "standard/recommended practice" in these is the default way in Rust, often enforced by compiler itself.
The naming convention for the trait names is horrible. It would be much more intuitive to use names like in swift protocols. Instead of a Hash trait it would be Hashable. Instead of Cast it would be Castable. It makes type and trait names different. A Hash is something that is a hash of something and Hashable is something that can be hashed.
Great talk! I'll have to say that as for trait objects I've read the two chapters in the book on traits multiple times and I'm not sure the name is appropriate. It's misleading a think because a trait object (unless I'm totally off base) seems nothing like an object in other languages. The implementations themselves are what bring behavior. It's not packaged with the data like in a traditional object. If you "create" a trait object by saying Vec then you aren't creating an object at all. It's more similar to trait bounds the way I see it. You are restricting what the smart pointer (box) points at by defining that it must be something that implements the cast trait. I think the name should be changed maybe, because I think the name 'trait object' is very misleading. If anyone can draw a parallel to traditional objects in other languages to justify the name I'd love to see one. I don't actually think the parallel she drew made sense because we don't package up the pointer with a method in the same location. Am I totally off base here?!
`Box` is a *fat pointer* that contains both a pointer to the data and a pointer to the vtable (virtual table) that has pointers to the method implementations.