Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does "dyn" mean in a type?

Tags:

syntax

rust

I have recently seen code using the dyn keyword:

fn foo(arg: &dyn Display) {}  fn bar() -> Box<dyn Display> {} 

What does this syntax mean?

like image 408
Shepmaster Avatar asked Jun 01 '18 19:06

Shepmaster


People also ask

When to use dyn in rust?

The dyn keyword is used when declaring a trait object: The size of a trait is not known at compile-time; therefore, traits have to be wrapped inside a Box when creating a vector trait object.

What is the Dyn keyword rust?

Keyword dyn The dyn keyword is used to highlight that calls to methods on the associated Trait are dynamically dispatched. To use the trait this way, it must be 'object safe'. Unlike generic parameters or impl Trait , the compiler does not know the concrete type that is being passed. That is, the type has been erased.

What is sized in Rust?

The Sized trait in Rust is an auto trait and a marker trait. Auto traits are traits that get automatically implemented for a type if it passes certain conditions. Marker traits are traits that mark a type as having a certain property.

What is trait object?

A trait object is an opaque value of another type that implements a set of traits. The set of traits is made up of an object safe base trait plus any number of auto traits. Trait objects implement the base trait, its auto traits, and any supertraits of the base trait.


2 Answers

TL;DR: It's a syntax for specifying the type of a trait object and must be specified 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.

dyn is short for "dynamic" and refers to the fact that trait objects perform dynamic dispatch. This means that the decision of exactly which function is called will occur at program run time. Contrast this to static dispatch which uses the impl Trait syntax.

The syntax without dyn is now deprecated and it's likely that in a subsequent edition of Rust it will be removed.

  • Why would I implement methods on a trait instead of as part of the trait?
  • What makes something a "trait object"?
like image 157
Shepmaster Avatar answered Sep 28 '22 06:09

Shepmaster


The dyn keyword is used to indicate that a type is a trait object. According to the Rust docs:

A trait object is an opaque value of another type that implements a set of traits.

In other words, we do not know the specific type of the object at compile time, we just know that the object implements the trait.

Because the size of a trait object is unknown at compile time they must be placed behind a pointer. For example, if Trait is your trait name then you can use your trait objects in the following manner:

  • Box<dyn Trait>
  • &dyn Trait
  • and other pointer types

The variables/parameters which hold the trait objects are fat pointers which consists of the following components:

  • pointer to the object in memory
  • pointer to that object’s vtable, a vtable is a table with pointers which point to the actual method(s) implementation(s).

See my answer on What makes something a “trait object”? for further details.

like image 44
Willem van der Veen Avatar answered Sep 28 '22 05:09

Willem van der Veen