You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The last paragraph of Defining a Trait for Common Behavior:
On the other hand, with the method using trait objects, one Screen instance can hold a Vec<T> that contains a Box<Button> as well as a Box<TextField>. Let’s look at how this works, and then we’ll talk about the runtime performance implications.
is incorrect, or at the least extremely misleading: Vec<T> should be Vec<Box<dyn Draw>>. Vec<T> is the type in the example code that uses generics, not trait objects, while Vec<Box<dyn Draw>> must be used in the example code using trait objects. The paragraph above is referring to the approach for trait objects, not generics.
This mistake leads the reader to think that Vec<T> should be used with the example code for trait objects. This adds to the confusion caused by another issue with the text in this section, which I believe should not have been closed.
Suggested fix:
A minimal fix is to change Vec<T> to Vec<Box<dyn Draw>> in the paragraph mentioned above.
In addition I think it would avoid a lot of confusion (see this URLO post) to repeat the following type near the top of the Implementing the Trait section:
pubstructScreen{pubcomponents:Vec<Box<dynDraw>>,}
This would make it clear that the Implementing the Trait section is referring to this type, not the last shown definition of that type (which uses Vec<T>). The example code in this section will not compile if Vec<T> is used.
I would be happy to take a shot at fixing this if it is approved.
The text was updated successfully, but these errors were encountered:
Hmm, I see the confusion here, but I think there is actually a deeper level of confusion highlighted by your comment. (To be extra clear, I am not saying this is your fault or problem!) When you write this—
The paragraph above is referring to the approach for trait objects, not generics.
—it indicates that you saw trait objects as being an alternative to generics. The text more or less says that, so: fair! But they are not—at least, not exactly. They are a different feature, which can be used with generics, and I think the confusion here (as well as in the other issue you opened) is due to the two related, but ultimately distinct, ways that the text uses “generics” here: to refer to Vec<T> as a component of Screen, and how to define Screen itself—with a generic using a trait bound, or just requiring a trait object. That is, the difference the text cares about is:
Screen using trait object:
pubstructScreen{pubcomponents:Vec<Box<dynDraw>>,}
Screen using constrained generic:
pubstructScreen<T:Draw>{pubcomponents:Vec<T>,}
The thing the text is distinguishing in this section is thus not between generics and trait objects per se, but rather two different ways you can specify what the generic type THIS TYPE is in the definition components: Vec<THIS TYPE>. The distinction is between using a trait objects there vs. a generic from Screen<T> with a trait bound. So I can see why at least some people are getting stuck here!
Because Vec<T> and Box<T> remain the normal ways to refer to those generic types, we might want to find a way to be a tiny bit clearer about when we are talking about them vs. when we are talking about Screen vs. Screen<T>. 🤔
Note
When you write Vec<Box<dyn Draw>>, you are still writing a specific instantiation of a generic type Vec<T>, as well as of the generic type Box<T>. Vec is always a “generic type”, generic over whatever T a given usage instantiates it with. (So is Box.) One way you can get a concrete type for it is with a “static” type like String, for example with Vec<String>. Another is with a pointer wrapping dyn Trait, for example with Vec<Box<dyn Draw>>. Both of those are a specific kind of Vec<T>. The text is trying to walk a fine line between precision/pedantry and saying just enough to cover the basic idea and keep moving toward the goal.
I have searched open and closed issues and pull requests for duplicates, using these search terms:
I have checked the latest
main
branch to see if this has already been fixed, in this file:URL to the section(s) of the book with this problem:
https://doc.rust-lang.org/book/ch17-02-trait-objects.html#defining-a-trait-for-common-behavior
https://doc.rust-lang.org/book/ch17-02-trait-objects.html#implementing-the-trait
Description of the problem:
The last paragraph of Defining a Trait for Common Behavior:
is incorrect, or at the least extremely misleading:
Vec<T>
should beVec<Box<dyn Draw>>
.Vec<T>
is the type in the example code that uses generics, not trait objects, whileVec<Box<dyn Draw>>
must be used in the example code using trait objects. The paragraph above is referring to the approach for trait objects, not generics.This mistake leads the reader to think that
Vec<T>
should be used with the example code for trait objects. This adds to the confusion caused by another issue with the text in this section, which I believe should not have been closed.Suggested fix:
A minimal fix is to change
Vec<T>
toVec<Box<dyn Draw>>
in the paragraph mentioned above.In addition I think it would avoid a lot of confusion (see this URLO post) to repeat the following type near the top of the Implementing the Trait section:
This would make it clear that the Implementing the Trait section is referring to this type, not the last shown definition of that type (which uses
Vec<T>
). The example code in this section will not compile ifVec<T>
is used.I would be happy to take a shot at fixing this if it is approved.
The text was updated successfully, but these errors were encountered: