@fieldwise_init
You can add the @fieldwise_init decorator on a struct to generate the
field-wise __init__() constructor.
For example, consider a simple struct like this:
@fieldwise_init
struct MyPet:
var name: String
var age: IntMojo sees the @fieldwise_init decorator and synthesizes a field-wise
constructor, the result being as if you had actually written this:
struct MyPet:
var name: String
var age: Int
fn __init__(out self, var name: String, age: Int):
self.name = name^
self.age = ageYou can synthesize the copy constructor and move constructor by adding the
Copyable trait to your struct. For more information about these
lifecycle methods, read Life of a value.
Implicit conversionโ
Implicit conversion lets you pass a value and lets a type build itself,
without calling the constructor directly. This keeps caller code simple and clean.
You enable this by marking an initializer as @implicit or using
@fieldwise_init("implicit") to create one for you.
For example, if MyStruct has an initializer that accepts an Int, you can
construct an instance like this:
an_instance = MyStruct(42)A function that takes a MyStruct will accept that instance, an explicit
constructor call, or the value that can be converted into one:
some_function(an_instance) # pass an instance
some_function(MyStruct(42)) # build one directly
some_function(42) # implicit conversionAll three forms create a MyStruct for the call. Some may have small
compile-time or run-time differences.
Declaring implicit initializationโ
You can declare implicit initializers in two ways:
- Use
@fieldwise_init("implicit")to auto-create one, as long as your type has exactly one instance field. This limit applies to the type itself, not just to initializer arguments. - Add
@implicitto an initializer you write. The initializer can accept only one argument.
Fieldwise and implicit exampleโ
Here is a type that stores an Int. It can be created with an integer
or from any value that can be floored and converted to an integer.
It uses @fieldwise_init("implicit") for integers and creates
an @implicit initializer for other values:
from math import Floorable, floor
# Creates an implicit initializer and limits the type to one instance field.
@fieldwise_init("implicit")
struct FlooringInt:
var floored: Int
# Allows implicit conversion from types that can be floored and made into an Int.
@implicit
fn __init__[T: Floorable & Intable](out self, value: T):
self.floored = Int(floor(value))
fn floored(value: FlooringInt) -> Int:
return value.floored
fn main():
print(floored(FlooringInt(42))) # pass an instance, output: 42
print(floored(2)) # pass Int, output: 2
print(floored(52.6)) # pass Float64, output: 52
x = BFloat16(192.3)
print(floored(x)) # pass BFloat16, output: 192
y: FlooringInt = 180
print(y.floored) # output 180
z: FlooringInt = 3.14159
print(z.floored) # output: 3What you don't see in this example is an initializer for integers.
Adding @fieldwise_init("implicit") lets the compiler build it for
you. If you wrote this by hand, it might look like this:
@implicit
fn __init__(out self, floored: Int):
self.floored = flooredWas this page helpful?
Thank you! We'll create more content like this.
Thank you for helping us improve!