Generic functions use [[static dispatch]], meaning that the type of all parameters that end up being used for the function must be known at compile time. Generic functions generate separate copies of the code for each combination of generic parameters used in a process called [[monomorphization]].{{sfn|Klabnik|Nichols|2023|pp=191-192}} Because monomorphization duplicates the code for each type used, it is as performant as writing functions using concrete types,{{sfn|Klabnik|Nichols|2023|pp=191-192}} but compile time and size of the output binary could be increased.{{sfn|Gjengset|2021|p=25}}
howeverHowever, Rust also uses a feature known as ''trait objects'' to accomplish [[dynamic dispatch]], a type of polymorphism where the implementation of a polymorphic operation is chosen at [[Runtime (program lifecycle phase)|runtime]]. This allows for behavior similar to [[duck typing]], where all data types that implement a given trait can be treated as functionally equivalent.{{sfn|Klabnik|Nichols|2023|loc=[https://doc.rust-lang.org/book/ch18-02-trait-objects.html 18.2. Using Trait Objects That Allow for Values of Different Types]}} Trait objects are declared using the syntax <code>dyn Tr</code> where <code>Tr</code> is a trait. Trait objects are dynamically sized, therefore they must be put behind a pointer, such as <code>Box</code>.{{sfn|Klabnik|Nichols|2019|pp=441–442}} The following example creates a list of objects where each object can be printed out using the <code>Display</code> trait: