Overview of Gosu generics

The greatest power of Gosu generics is defining an API that works with multiple types, not just a single type. To specify that an item is not restricted to a single type requires a syntax called parameterization. Functions defined with generics clarify the relationships among the types of parameters and return values. For example, even though the type of a parameter is generic, the return value can be strongly typed to match the exact type of that parameter. Generics are particularly useful in specifying the type of object that a collection parameter or return value contains. For example, the method returns a “list of MyClass objects” or “a MyClass object”, rather than a “list of Object objects” or just “an Object object”.

If a method uses Gosu generics to define arguments or a return value, the API is straightforward to use for an API consumer. The syntax for defining the type of item is angle bracket notation such as CLASS<USING_TYPE>, FUNCTION<USING_TYPE>, or COLLECTION_CLASS<OF_TYPE>. The parameterized definition of a method or class uses a generics wildcard type inside the angle brackets. By convention, the symbol for the wildcard type is T, so the generics syntax is <T>. To use a collection that is an argument to or return value from a method that uses generics, you define the collection as a specific type. For example, the following line defines a list of String objects, which you can use as an argument to a generic method.

var myStrs = new ArrayList<String>() { address1, address2, address3, address4 }
Note: In practice, you sometimes do not need to define the type because of type inference or special object constructors. For example, var myStrs = { "a", "ab", "abc"} is equivalent to var myStrs = new ArrayList<String>() { "a", "ab", "abc"}.
You can create a method that parameterizes an argument as a specific type of list, in this case a list of strings. This argument has an explicit type and does not use generics to support multiple types of array list. The code in the method uses methods that are specific to the String type, so does not support other list types.
function printStrings( strs : ArrayList<String> ) {
  for ( s in strs ) {
    print( "${s} ${s.length}" )
  }
}

To call a method that uses a parameterized argument type, call the method in the usual way:

printStrings( myStrs )

A compile-time error occurs if you use an argument that does not match the parameterized specification on a method that uses Gosu generics to specify the argument type:

printStrings( {1, 2, 3, 4} ) // Array list of Integer is not an array list of String

Parameterizing collections and other containers is a typical use of generics, but Gosu does not limit generics support to only container types. You can define any class to use Gosu generics to generalize what the class supports or how the class works with various types.

Gosu provides two ways to use generic types:

  • You can parameterize a class, which adds generic types to a class definition.
  • You can parameterize a method, which adds generic types to a method definition.