Object construction [language.objconstr]
Use Xxx(x: 42, y: Yyy(z: 54))
style, or if type has an init
function, Type.init(a, b, c)
.
Prefer that the default 0-initialization is a valid state for the type.
# `init` functions are a convention for constructors - they are not enforced by the language
func init(T: type Xxx, a, b: int): T = T(
x: a,
y: OtherType(s: b) # Prefer Type(field: value)-style initialization
)
let m = Xxx.init(1, 2)
# `new` returns a reference to the given type:
func new(T: type Xxx, a, b: int ): ref T = ...
# ... or `init` when used with a `ref Xxx`:
func init(T: type (ref Xxx), a, b: int ): T = ...
Pros
- Correct order of initialization enforced by compiler / code structure
- Dedicated syntax constructs a clean instance resetting all fields
- Possible to build static analysis tools to detect uninitialized fields
- Works for both
ref
and non-ref
types
Cons
- Sometimes inefficient compared to updating an existing
var
instance, since all fields must be re-initialized - Compared to
func newXxx()
,func new(T: type Xxx)
will be a generic procedure, which can cause issues. See Import, export
Practical notes
- The default, 0-initialized state of the object often gets constructed in the language - avoiding a requirement that a magic
init
function be called makes the type more ergonomic to use - Avoid using
result
orvar instance: Type
which disable several compiler diagnostics - When using inheritance,
func new(T: type Xxx)
will also bind to any type inheriting from Xxx