Named constructors
JN
666total at wp.pl
Sat Nov 9 00:02:52 UTC 2024
Let's say you want to have an Angle class, which holds radians
internally but can be initialized with degrees or radians.
```d
class Angle
{
float radians;
this(float rad) : radians(rad) { }
this(float degs) : radians(degs * (PI / 180.0f)) { }
}
Angle a = new Angle(90.0f);
```
Won't work, because you can't have two constructors with same
args. Of course you can work it around by e.g. wrapping them in
some "Degree" and "Radian" struct so that they're separate type
and overloads.
Next option, static factory methods:
```d
class Angle
{
float radians;
// hide constructor so that users use the factory methods
private this(float rad) { radians = rad; }
static Angle fromRadians(float rad) { return new Angle(rad); }
static Angle fromDegrees(float degs) { return new Angle(degs
* (PI / 180.0f)); }
}
Angle a = Angle.fromDegrees(90.0f);
```
This works, but is awkward because suddenly you don't use the new
keyword and it's not immediately obvious that these methods are
meant to be used for construction of the object. After typing
"Angle." an IDE will suggest all static methods on the class
which can be a long list.
Named constructors to the rescue:
```d
class Angle
{
float radians;
this.fromRadians(float rad) : radians(rad) { }
this.fromDegrees(float degs) : radians(degs * (PI / 180.0f))
{}
}
Angle a1 = new Angle.fromRadians(PI / 2.0f);
Angle a2 = new Angle.fromDegrees(90.0f);
```
Much clearer for the user, user can type "new Angle." and the IDE
would suggest only constructors instead of all of the static
methods on the class. Assumption would be that if named
constructors exist, there is no implicit argumentless constructor
so Angle a3 = new Angle() won't work anymore.
More information about the dip.ideas
mailing list