# record custom type

  • The record type is similar to the C language struct syntax. You can customize the structure with several attribute fields. Each attribute field has its own type. Different attributes can have different types. The type of the attribute can also be other records. Types, that is, you can nest record types.

    such as:

    type Address = {
        province: string,
        city: string
    }

    type Person = {
        name: string,
        age: int default 24,
        age2: int = 24,  -- The default value of the record attribute can be either default or = to distinguish
        address: Address,
        parent_names: Array<string>
    }
  • The initialization and assignment of the record can be assigned using the table. The record type variable or function return value can also be assigned to the table type variable without additional type conversion. The record attributes and attribute values correspond one-to-one with the table keys.

such as:

    type Person = {
        name: string,
        age: int default 24
    }

    type Address = {
        province: string,
        city: string
    }

    var p1: Person = {name='glua'} -- Use Map<T> value to assign value to record type variable, will do automatic type conversion
    var p2: Address = p1           -- Compile error, p1 is a variable of type Person and cannot be assigned to a variable of type Address
    var p3: table = p1             -- Correct, variable or value of record type can be assigned to variable of table type
  • The record type is only a declaration of the type of the variable, but it is actually still a table type at runtime. If the record is created with a constructor (the name of the type constructor and the name of the type are the same name), you can use a table value as a parameter to initialize, and the attribute without a value will use the default value of the attribute. If you use a table type value such as {} for type conversion and assign it to the record type, there is no constructor call, and the default value of the attribute of the record type does not work.

    The storage of the contract is initialized directly by the blockchain, and the default attribute value of the record type does not work on it

such as:

    type Person = {
        name: string,
        age: int default 24,
        age2: int = 24  -- The default value of the record attribute can be either default or = to distinguish
    }
    let p1 = Person()                        -- The p1 value is {name: nil, age: 24, age2: 24}
    let p2 = Person({name='glua'})           -- The p2 value is {name: 'glua', age: 24, age2: 24}
    let p3 = Person({name='glua', age=100})  -- The p3 value is {name: 'glua', age: 100, age2: 24}
    let p4: Person = {}                      -- The p4 value is {}
  • The record can be defined with several generic parameters. Generic parameters can be used to define the attribute type in the record attribute type. The record type with generic parameters needs to be instantiated with a specific type before it can be used to declare variable or function parameter types.

such as:

    type Person<A> = {  -- A is the generic parameter of Person generic, which is a type variable used to represent an unknown type
        name: string,
        address: A      -- If the address attribute is declared as type A, the type of the address attribute is determined according to the specific type of A when the Person generic is instantiated
    }
    let p = Person<string>()  -- Here first replace the A type variable of Person generic type with string type to generate a new type Person<string>, and then call the constructor of this new type
  • • the definition of a member function of the record, can not use function <varname>.<funcname> (...) ... end syntax, only with function <varname>:<funcname> (...) ... end grammar

such as:

    type Person = {
        name: string,
        age: int
    }
    var p1 = {}
    function p1.sayHi1(self)    -- Correct
    end
    function p1:sayHi2()    -- Correct
    end
    
    var p2 = Person()
    function p2.sayHi1(self)    -- Compile error, p2 is record type, you can not define member function in the way of varname.funcName
    end
    function p2:sayHi2()        -- Correct
    end

    p1:sayHi1()                 -- Correct
    p1:sayHi2()                 -- Correct
    p2:sayHi2()                 -- Correct
  • The grammar of record without specific instructions is Mapconsistent with the grammar. You can also use varname.propertyName and varname['propertyName'], varname["propertyName"} to read and modify the properties of record type variables
  • The syntax defined by record is:
    type RecordName = { PropName: PropTypeName, … }

or

    type RecordName <GenericType1, … > = { PropName: PropTypeName, … }

E.g:

    type Person = { 
        name: string,
        age: int,
        mobile ?: string default ''                  --  This means that the type of attribute mobile is string | nil, and the default value is an empty string
    }
    type G1<T1, T2, T3> = { a: T1, b: T2, c: T3, count: int }
  • record can be used to define new records with other names, and can also have new generic parameters (optional)

The syntax is as follows:

    type RecordName = RecordNameExisted < Type1, … >

or

    type RecordName = RecordNameExisted

or

    type RecordName <GenericType1, … > = RecordNameExisted < Type1, … >

or

    type RecordName <GenericType1, … > = RecordNameExisted

E.g:

    type G2<T> = G1<int, T, string>
    type G3 = G1<string> -- 编译报错,G1需要3个类型变量
    type G4 = string
    type G5 = G4
  • After the record type is defined, a function of the same name is automatically generated as a constructor. It can optionally accept a Maptype of parameter. MapSome attributes in the parameter override the default value of the Maprecord type . The merged record type is used as the return value of the constructor.

  • The constructor of the calling type can also omit the brackets and directly pass a map literal as a parameter

E.g:

    type Person = { name: string, age: int default 100 }
    let p1 = Person()                        -- The value of p1 is {name: nil, age: 100}
    let p2 = Person({name: "glua"})           -- The value of p2 is {name: "glua", age: 100}

    let p3 = Array<Person> (  [ {name: "glua"}, {name: "China", age: 10000} ] )   -- The parentheses cannot be omitted here, because the parameter is an array literal and not a map literal
    let p4 = Array<Person> { name: "hello", age: 100 }