MusicHoard with dyn Trait or generics? #93

Closed
opened 2024-01-11 23:27:39 +01:00 by wojtek · 1 comment
Owner

Basically the undoing of #31

Basically the undoing of #31
wojtek added the
chore
label 2024-01-11 23:29:45 +01:00
Author
Owner

https://www.lurklurk.org/effective-rust/generics.html

In summary: prefer generics.

Details:

The balance of factors so far leads to the advice to prefer generics to trait objects, but there are situations where trait objects are the right tool for the job.

The first is a practical consideration: if generated code size or compilation time is a concern, then trait objects will perform better (as described at the start of this Item).

A more theoretical aspect that leads towards trait objects is that they fundamentally involve type erasure: information about the concrete type is lost in the conversion to a trait object. This can be a downside (see Item 19), but it can also be useful because it allows for collections of heterogeneous objects – because the code just relies on the methods of the trait, it can invoke and combine the methods of differently (concretely) typed items.

The traditional OO example of rendering a list of shapes would be one example of this: the same render() method could be used for squares, circles, ellipses and stars in the same loop.

    let shapes: Vec<&dyn Shape> = vec![&square, &circle];
    for shape in shapes {
        shape.render()
    }

A much more obscure potential advantage for trait objects is when the available types are not known at compile-time; if new code is dynamically loaded at run-time (e.g via dlopen(3)), then items that implement traits in the new code can only be invoked via a trait object, because there's no source code to monomorphize over.

None of these are concerns at the moment.

https://www.lurklurk.org/effective-rust/generics.html In summary: prefer generics. Details: > The balance of factors so far leads to the advice to prefer generics to trait objects, but there are situations where trait objects are the right tool for the job. > > The first is a practical consideration: if generated code size or compilation time is a concern, then trait objects will perform better (as described at the start of this Item). > > A more theoretical aspect that leads towards trait objects is that they fundamentally involve type erasure: information about the concrete type is lost in the conversion to a trait object. This can be a downside (see Item 19), but it can also be useful because it allows for collections of heterogeneous objects – because the code just relies on the methods of the trait, it can invoke and combine the methods of differently (concretely) typed items. > > The traditional OO example of rendering a list of shapes would be one example of this: the same render() method could be used for squares, circles, ellipses and stars in the same loop. > > ```rust > let shapes: Vec<&dyn Shape> = vec![&square, &circle]; > for shape in shapes { > shape.render() > } > ``` > > A much more obscure potential advantage for trait objects is when the available types are not known at compile-time; if new code is dynamically loaded at run-time (e.g via dlopen(3)), then items that implement traits in the new code can only be invoked via a trait object, because there's no source code to monomorphize over. None of these are concerns at the moment.
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: wojtek/musichoard#93
No description provided.