import ballerina/io;
type Student record {
    string name;
    int age;
    Grades grades;
    string...;
};
type Grades record {|
    int maths;
    int physics;
    int chemistry;
|};public function main() {
    Student john = {name: "John Doe", age: 17,
                    grades: {maths: 80, physics: 75, chemistry: 65}};
    io:println(john);
    io:println(john.name);
    io:println(john["name"]);
    io:println(john.grades.maths);    Student peter = {name: "Peter", age: 19,
                     grades: {maths: 40, physics: 35, chemistry: 35}};
    peter.age = 16;    io:println(peter);
    io:println(john);
    peter.department = "Computer Science";
    io:println(peter);
}

Record

In Ballerina, records are a mapping type. However, the keys (fields) are named and their types define the types of values allowed for the fields. If the set of fields is fixed, the record is called a “closed record”. If the set of fields is not fixed, the record is called an “open record”.

import ballerina/io;
type Student record {
    string name;
    int age;
    Grades grades;

This defines an open record type named Student which in addition to the fields defined here, allows additional string fields.

    string...;
};

This is a string typed rest field. All additional fields should be of the rest field’s type or a subtype of it. In the absence of an explicit rest field, an implicit rest field of type anydata|error is assumed.

type Grades record {|
    int maths;
    int physics;
    int chemistry;
|};

This defines a closed record type named Grades. Closed records are defined using the {| and |} delimiters.

public function main() {
    Student john = {name: "John Doe", age: 17,
                    grades: {maths: 80, physics: 75, chemistry: 65}};
    io:println(john);

This creates a Student record. Since all the fields are required and none of the fields have explicit default values assigned to them, values must be specified for all the fields when creating the record.

    io:println(john.name);

This is an example of field-based access of record fields. The return type of this expression is the type of the field. If it is an open record and the specified key is not present in the record at run time, it will result in a panic. If it is a closed record, accessing an undefined key will result in a compilation error.

    io:println(john["name"]);

This is an example of index-based access of record fields. The return type of this expression is T?, where T is the type of the field. If it is an open record and the specified key is not present in the record at run time, () will be returned. If it is a closed record, accessing an undefined key will result in a compilation error.

    io:println(john.grades.maths);

This fetches a field of a nested record.

    Student peter = {name: "Peter", age: 19,
                     grades: {maths: 40, physics: 35, chemistry: 35}};
    peter.age = 16;

This modifies the value of the age field.

    io:println(peter);
    io:println(john);
    peter.department = "Computer Science";
    io:println(peter);
}

This adds an additional field not defined in the record type descriptor above. Note that an attempt to add additional fields to a closed record results in compile errors. e.g., peter.grades.ict = 77; will result in a compile error.

# To run this sample, navigate to the directory that contains the
# `.bal` file and execute the `ballerina run` command.
$ ballerina run records.bal
{name:"John Doe", age:17, grades:{maths:80, physics:75, chemistry:65}}
John Doe
John Doe
80
{name:"Peter", age:16, grades:{maths:40, physics:35, chemistry:35}}
{name:"John Doe", age:17, grades:{maths:80, physics:75, chemistry:65}}
{name:"Peter", age:16, grades:{maths:40, physics:35, chemistry:35}, department:"Computer Science"}