1

I am trying to avoid specifying multiple traits on each use of generic type T. Can I use the newtype idiom to specify bounds once? This works but I'll have the where ... on each function.

fn prn<T>(arg: T)
where
    T: std::fmt::Debug + Copy,
{
    println!("{:?}", arg);
}

fn main() {
    let x: i32 = 1;
    prn(x);
}

Would it be possible to use a newtype like below to let me make fn prn generic and not have to specify all the traits on each impl?

pub struct MyData<T>(T)
where
    T: std::fmt::Debug + Copy + Clone + std::ops::Add<Output = T>;

My failed attempt below:

// WRONG - won't compile - is there syntax for newtype as type param?
fn prnt<MyData<T>>(arg: T) {
    println!("{:?}", arg);
}

fn main() {
    let x: i32 = 1;
    prnt(x);
}
navicore
  • 1,979
  • 4
  • 34
  • 50

1 Answers1

2

Would it be possible to use a newtype like below

No. A newtype is a concrete type, it's not any sort of constraint.

You can use trait inheritance and blanket implementations to "bundle" traits:

trait Thing: std::fmt::Debug + Copy + Clone {}

impl <T>Thing for T where T: std::fmt::Debug + Copy + Clone {}

fn foo<T: Thing>(v: T) {
    println!("{v:?}");
}
fn main() {
    foo("bar");
    foo(1);
    foo(false);
}

And while I don't think you can use macros to declare generic constraints (which would be an alternative) if you need many such traits you can use macros to declare the traits & blanket impls in one shot: https://stackoverflow.com/a/57848887/8182118

Masklinn
  • 34,759
  • 3
  • 38
  • 57