Trait bound vs. dyn keyword

Is there any difference between these two approaches? The both seem to work fine.

use core::fmt::Debug;

#[derive(Debug)]
struct Point2D {
    x: f64,
    y: f64
}

impl ToString for Point2D {
    fn to_string(&self) -> String {
        format!("({}, {})", self.x, self.y)
    }
}

// Approach #1: fn print_string(label: &str, value: &dyn ToString) {
// Approach #2: fn print_string<T: ToString>(label: &str, value: &T) {
fn print_string(label: &str, value: &dyn ToString) { // using approach #1 here
  println!("{}: {}", label, value.to_string());
}

fn main() {
  print_string("Name", &"Mark"); // Name: Mark
  print_string("Score", &19); // Score: 19
  let pt = Point2D { x: 1.2, y: 3.4 };
  print_string("Point", &pt); // Point: (1.2, 3.4)
}

(Playground)

Output:

Name: Mark
Score: 19
Point: (1.2, 3.4)

Errors:

   Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 0.89s
     Running `target/debug/playground`

Yes, when using dyn ToString, the executable will contain only one version of print_string, but when using <T: ToString>, the executable will contain a separate copy of print_string for each type T you use it with.

Note that using impl ToString is equivalent to <T: ToString>, and not to dyn ToString.

7 Likes

If I want the parameter to implement more than one trait, I can do this which works:

fn print_string<T: Debug + ToString>(label: &str, value: &T) {

How can I specify multiple traits with the dyn keyword?
I tried this, but the compiler doesn't like it:

fn print_string(label: &str, value: &(dyn Debug + ToString)) {

Trait objects only allow one "real" trait. To use multiple traits, define a helper trait

use std::fmt::Debug;

fn print_string(label: &str, value: &(dyn DebugAndToString)) {
}

trait DebugAndToString: Debug + ToString {}
impl<T: Debug + ToString> DebugAndToString for T {}
6 Likes

Thanks so much Alice! You've been SO helpful to me!

...and will be able to optimize them separately, knowing the exact implementation of trait, which is sometimes important.

2 Likes
1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.