Adding static constant variables to a structural type

In both Gosu and Java, you can add static variables to types to declare data that exists at the type level. For Gosu classes, you add such data to a class by adding a declaration line with the static modifier:

public static var MyVariable

For structural type definitions, any variables that store state are implicitly static and constant so you can omit the word static:

public var MyVariable

Adding a var declaration does not imply the ability to get or set a variable or property on an instance of the type. A var declaration on a structural type defines a static constant variable on the type. A static constant variable is conceptually similar to a static variable on a Gosu class. However, as for a variable on an interface, the static keyword is implicit and the value is read-only. The declaration does not specify the ability to get or set a variable or property an instance of this type.

For example, note the Age variable in the following example:

package docs.example

structure DemoStructure2 {
  property get Name() : String
  property set Name(n : String)
  public var Age : Integer      // Compilation error. A static constant variable requires initialization
}

The var declaration on the structural type creates a static constant variable, which must be initialized, so the previous code causes a compilation error. Initializing the value of the static constant variable clears the error:

package docs.example

structure DemoStructure2 {
  property get Name() : String
  property set Name(n : String)
  public var AGE : Integer = 18 // OK because the static constant variable is intialized
}

You can add the static modifier in the declaration of the AGE variable, but in structural type declarations, this modifier is implicit and therefore redundant.

Although you can use property getter and setter syntax to define data to get and set on instances, you do not use this syntax for static constant variables. Therefore, static constant variables do not require assignment compatibility between the structural type and other types.

The DemoStructure2 class from the previous example is compatible with the following class:

package docs.examples

class MyClass {
  public var Name: String
  public var UnusedField1: String
  public var UnusedField2: String
}

Notice the following characteristics of MyClass:

  • The Gosu class MyClass has a Name variable, which is the only requirement to be compatible for assignment to a variable of the structural type DemoStructure2. Because MyClass is a Gosu class and not a structural type, the Name variable is a natural instance variable and is not static. Instance variables and properties on a concrete type are compatible with getters and setters on the structural type, so these are compatible names and types.
  • The Gosu class MyClass does not have an AGE variable or property. Because the AGE variable on the structural type is a static constant, it exists on the structural type only. For a static constant variable, the concrete type does not require compatibility for assignment between the types.

For example, you can now run the following code in the Gosu Scratchpad:

uses docs.examples.DemoStructure2

uses docs.examples.MyClass

var obj : MyClass
var struct : DemoStructure2

// Create a new instances of the concrete type
obj = new MyClass()

// Assign the MyClass object to a variable declared as the structural type
struct = obj

// Set the shared field on the variable of the structural type, and it affects both
struct.Name = "John"
print("struct.Name is " + struct.Name)
print("obj.Name is " + obj.Name)

// Set the shared field on variable of type MyClass, and it affects both
obj.Name = "Eric"
print("struct.Name is " + struct.Name)
print("obj.Name is " + obj.Name)

// struct.AGE is a STATIC CONSTANT and is not shared, and is read-only
print("struct.AGE (a STATIC CONSTANT) is " + struct.AGE)

// The following line is not valid if you uncomment it. Static constant fields are READ-ONLY.
// struct.AGE = 40

This code prints the following:

struct.Name is John
obj.Name is John
struct.Name is Eric
obj.Name is Eric
struct.AGE (a STATIC CONSTANT) is 18

See also