module Constructors {
// CONSTUCTOR BASICS
struct Wall {
width : int;
height : int;
area : int;
}
// define exception type
except ZeroSize{size : int}
// constructor functions can be defined for structs
// • once a constructor function is defined it is used for all construction of the type.
// • constructors functions must be defined in the same module that defines the type.
// • if a constructor function is private, then only the defining module can create the type.
// • the return type is the type being constructed. within the scope of the constructor
// the default constructor for the type will be used instead of the constructor
// being defined.
constructor(width : int, height : int) : Wall => {
if (width == 0) {
throw ZeroSize(width);
}
if (height == 0) {
throw ZeroSize(height);
}
// NOTE: within the constructor function, the default constructor is used
return Wall(width, height, width * height);
}
fn test1() {
let w1 = Wall(4, 8); // calls constructor to initialize Wall
let w2 = Wall(4, 0); // constructor raises ZeroSize exception
}
// GENERIC CONSTRUCTORS
// constructors can be generic, for example if the fields are generic
// or the parameters to the constructor are generic.
// define exception used by Distance constructor
except UnitMissing{}
// define Distance struct with generic parameter T for distance
struct Distance{T} {
value : T;
units : string;
}
// Constructor for generic Distance struct with generic T parameter
constructor{T}(value : T, unit : string) : Distance{T} => {
if (unit == "") {
throw UnitMissing;
}
return Distance(value, unit);
}
fn test2() {
let d1 = Distance{int}(1, "feet"); // construct Distance with int type
let d2 = Distance{double}(2.0, "meters"); // construct Distance with double type
// since the compiler can infer the generic type, the following are equivalent to the above
let d3 = Distance(1, "feet"); // construct Distance with int type
let d4 = Distance(2.0, "meters"); // construct Distance with double type
}
}