Multiple dimensionality generics

Typical use of generics is with one-dimensional objects, such as lists of a certain type of object. For example, a list of String objects or a collection of Address objects are one-dimensional.

Gosu generics are flexible and support multiple dimensions, just like Java generics. Generics that specify multiple dimensions can define the use of a Map, which stores a set of key-value pairs and is like a two-dimensional collection.

By using generics, you can define behavior for multiple types of maps. For example, you can use two-dimensional generics to define a method signature:

public function getHighestValue( theMap : Map<K,V>) : V

The parameter theMap has type Map. Gosu generics uses two wildcard types as single capital letters separated by commas to parameterize the types in the map. By convention, the first wildcard type (K) represents the type of the key and the second wildcard type (V) represents the type of the value. Because the method signature uses the V again in the return value type, the Gosu compiler makes assumptions about relationships between the type of map and the return value. The two uses of V in the method signature specify the same type for both the map value in the parameter and the return value.

At run time, the symbols K and V are assigned to specific types. The code that calls the method creates new instances of the parameterized class with specific types. The compiler can determine which method to call and the types that K and V represent.

A specific type of map that has keys of type Long and values of type String has a definition like the following line of code.

Map<Long, String> contacts = new HashMap<Long, String>()

If you pass the variable contacts to this getHighestValue method, the compiler knows that this call to the method returns a String value.

You can also define a class that uses multiple dimensions of types. For example, to work with key-value maps, you can use generics to define a class:

class Mymapping<K,V> { 
  public function put( key : K, value : V) {...} 
  public function get( key : K) : V {...} 
}

In the method definitions, the values in angle brackets have the same meanings as the type names in the parameterized class definition. In this example, the K and V symbols specify the types. Use these symbols in method signatures in the class to represent types in arguments, return values, and Gosu code inside the method. You can use this class to provide strongly typed results.

In the following example, the concrete types are String for K and Integer for V.

var myMap = new Mymapping<String, Integer>()
myMap.put("ABC", 29)

var theValue = myMap.get("ABC")

The theValue variable is strongly typed at compile time as Integer.

Because the code is strongly typed at compile time, the reliability of the code improves at run time.