Adding trait New to the standard library


#1

Looking through different Rust code examples I find out that we have a Drop trait that works as destructor but we don’t have trait for constructor. Instead everywhere we are using constructions like this:

impl MyStruct {
  fn new() -> MyStruct { ... }
}

I’m suggesting to add following trait:

trait New {
  fn new() -> Self;
}

so now structures that implement this trait can be created with default constructor in generic structures, traits and methods.

See playground example .

I was also thinking about trait method with parameters. Idea is following:

trait New {
  fn new(params: &()) -> Self;
}

but this of course doesn’t work. Maybe someone has an idea how to pass variadic parameters in Rust?

What do you think about my idea?


#2

That sounds a lot like the Default trait?


#3

Oops! I forget about it.
What about a version with multiple parameters? Would it be possible to create such a trait?

Upd: Why do we have 2 approaches for default constructor: new function and Default trait? Why not just use one?


#4

Drop is a trait because it allows the compiler to know when a type has a destructor that needs to be run.

What use case do you envision for this trait?


#5

I don’t have real use case right now but what I can think about is some Factory and Builder patterns that accept list of generic types and probably some parameters and generate more complex structures out of them using T::new(…).

UPD. Something like:

let builder = Builder::new();

let obj = builder.build::<T1, T2, T3>(10, 3.5, "test");

and function build looks like:

struct Builder{
  fn builder<T1, T2, T3>(v1: i32, v2: f32, v3: &str){
    let t1 = T1::new((v1, v2, v3));
    let t2 = T2::new((v1, v2, v3));
    let t3 = T3::new((v1, v2, v3));

    // compose t1, t2 and t3
    ...
  }
}

Syntax probably is not correct but main idea should be clear.

UPD2. In C++ you would use for this variadic templates and std::forward.


#6

T::new() in Rust is a static factory method, so you need to know what you are creating in order to call it. Do you plan to use this New trait in a generic method only?

Because if you want to use the trait for an abstract factory, the return value needs to be boxed in some way. And if it is boxed, it does matter what kind of boxing it gets (Box, Rc, Arc…), but deciding that should be the responsibility of the factory, not the type being instantiated.