import ballerina/io;type Gender "male"|"female";type Person record {
    string fname;
    string lname = "";    Gender gender;
    int age?;
};public function main() {
    Person john = {fname: "John", gender: "male"};
    io:println("Person with the non-defaultable required field set: ", john);
    int? age = john?.age;
    io:println("Age before setting: ", age);
    john.age = 25;
    age = john?.age;
    io:println("Age after setting: ", age);
    Person jane = {fname: "Jane", lname: "Doe", gender: "female"};
    io:println("Person with values assigned to required fields: ", jane);
}# To run this sample, navigate to the directory that contains the
# `.bal` file, and execute the `ballerina run` command below.
ballerina run record_optional_fields.bal
Person with the non-defaultable required field set: fname=John lname= gender=male
Age before setting: 
Age after setting: 25
Person with values assigned to required fields: fname=Jane lname=Doe gender=female

Optional Fields

Fields of a record can be marked as optional. These fields can be omitted when creating a record. Such fields can be accessed via optional field access (e.g., p?.name) or member access (e.g., p[“name”]) which will both return () if the field is not present in the record.

import ballerina/io;
type Gender "male"|"female";
type Person record {
    string fname;

This is a required field without an explicit default value. The compiler will not assign default values. Therefore, a value should be specified for this field when creating the record.

    string lname = "";

This is a required field with an explicit default value specified.

    Gender gender;
    int age?;
};

Adding ? following the identifier marks the field as an optional field.

public function main() {
    Person john = {fname: "John", gender: "male"};

The required fields fname and gender are not given default values in the record type descriptor. Therefore, values must be specified for fname and gender when creating the record.

    io:println("Person with the non-defaultable required field set: ", john);

The age field is not present in the record since it is an optional field.

    int? age = john?.age;
    io:println("Age before setting: ", age);

Optional fields of the record can be accessed using the ?. operator. This returns the value if the field is present in the record. Returns () if not. Since the age field is not set, optional field access returns () here.

    john.age = 25;

Now set a value for the age field. Field access can be used to set the value since age is a field defined in the type descriptor for Person.

    age = john?.age;
    io:println("Age after setting: ", age);

Since the age field is set, optional field access returns the int-typed value.

    Person jane = {fname: "Jane", lname: "Doe", gender: "female"};

Create a Person-typed value specifying a value for the defaultable field lname.

    io:println("Person with values assigned to required fields: ", jane);
}

Field values provided when creating a record takes highest precedence.

# To run this sample, navigate to the directory that contains the
# `.bal` file, and execute the `ballerina run` command below.
ballerina run record_optional_fields.bal
Person with the non-defaultable required field set: fname=John lname= gender=male
Age before setting: 
Age after setting: 25
Person with values assigned to required fields: fname=Jane lname=Doe gender=female