7.6. Structs
Like tuples, a struct is a way of grouping multiple values with
different types into an aggregate data structure.
The main differences between tuples and structs are that the fields of a struct
are named, and the type signature of a struct is named as a user defined type.
Any type except tuple and streams may be stored within
a struct.
7.6.1. Declaration
A struct is declared with the keyword struct followed by a type name,
followed by a parentheses-surrounded, comma-separated list of
field declarations.
Field declarations look identical to parameter declarations in functions,
and consist of a <type id> pair:
struct s1 (integer i, real r, integer[10] iv) t1;
struct Another (character char, real float, string[256] str, s1 struct_field);
var Another t2;
The examples show two structs declared with types s1 and another.
Struct type s has three fields: i of type integer, r of type
real, and iv of type integer[10].
Struct type another has four fields named char, float, str,
and struct_field.
The instance variables are t1 and t2 have types s1 and another,
respectively.
7.6.2. Access
The fields of a struct are accessed using dot notation, as in tuples.
Dot notation can only be applied to struct instances and not struct literals.
Dot notation can be specified as <id>.<field>, where:
idis an instance identifier/name of a struct of typeT
.is a literal period (dot)
fieldis a field within structT
For example:
struct s1 (integer i, real r, integer[10] iv) t1;
t1.i
t1.iv[2]
t1.r
Struct fields can be used as both LVALs and RVALs, i.e. on either the left or right hand side of an expression:
y = x + t1.r; // Allowed
t1.iv[i] = type-expr; // Allowed
7.6.3. Literals
A struct literal is constructed by listing comma separated values for each
field in the struct, in the order defined in the struct’s definition.
The value list is surrounded by parenthesis and prefaced by the struct type:
struct S (integer i, character[5] c, integer[3] a3);
const S cs = S(x, "hello", [1, 2, 3]);
var S vs = S(0, ' ', 0);
struct V (integer i, real r, integer[10] arr) v = V(1, 2.1, [i in 1..10 | i]);
The type of each value in the list must match the type of the corresponding field definition in the struct. To save having to explicitly specify a value for each index in an array, Gazprea allows a single scalar to be propagated across all elements in the array. Finally, note that the field values may need to be evaluated at run-time.
7.6.4. Operations
The following operations are defined on struct instances.
In all of the usage examples, struct-type means some struct yielding
expression of a particular type, while id is a field within the struct.
Class |
Operation |
Symbol |
Usage |
Associativity |
Access |
dot |
|
|
left |
Comparison |
equals |
|
|
left |
not equals |
|
|
left |
Note that in the above table struct-type may only refer to a variable
instance for Access, while for Comparison at least one of the operands must
resolve to a struct type T.
This allows struct instances to be compared to struct literals:
struct Complex (real r, real i) c = (r, 0.0);
if (c == Complex(0.0, i)) { }
Two structs are equal when all fields within each struct have the same value. It is an error to compare two structs of different types.
7.6.5. Type Casting and Type Promotion
A struct itself cannot be cast or promoted. However, the fields within a struct can be individually cast/promoted, as described in sections Type Casting and Type Promotion.