I have recently seen code using the dyn
keyword:
fn foo(arg: &dyn Display) {}
fn bar() -> Box<dyn Display> {}
What does this syntax mean?
I have recently seen code using the dyn
keyword:
fn foo(arg: &dyn Display) {}
fn bar() -> Box<dyn Display> {}
What does this syntax mean?
TL;DR: It's syntax for specifying the type of a trait object and should be preferred for clarity reasons.
Since Rust 1.0, traits have led a double life. Once a trait has been declared, it can be used either as a trait or as a type:
// As a trait
impl MyTrait for SomeType {}
// As a type!
impl MyTrait {}
impl AnotherTrait for MyTrait {}
As you can imagine, this double meaning can cause some confusion. Additionally, since the MyTrait
type is an unsized / dynamically-sized type, this can expose people to very complex error messages.
To ameliorate this problem, RFC 2113 introduced the dyn
syntax. This syntax is available starting in Rust 1.27:
use std::{fmt::Display, sync::Arc};
fn main() {
let display_ref: &dyn Display = &42;
let display_box: Box<dyn Display> = Box::new(42);
let display_arc: Arc<dyn Display> = Arc::new(42);
}
This new keyword parallels the impl Trait
syntax and strives to make the type of a trait object more obviously distinct from the "bare" trait syntax.
It's likely that in a subsequent edition of Rust, the bare syntax will be deprecated and then eventually removed.