Generics#
Generic programming is a way of defining that something is applicable to a variety of potential types, without having to know these types before hand. The classic example would be a collection such as a list, which can be trivially customised to contain any type of data elements. Generics allow a Vala programmer to have these customisations done automatically.
Some of these are possible, which?
class Wrapper<T> : Object { … }
new Wrapper<Object> ();
BUG: class StringWrapper : Wrapper<string> () { … }
FAIL: class WrapperWrapper<Wrapper<T>> : Object { … }
FAIL: new WrapperWrapper<Wrapper<Object>> () ;
interface IWrapper<T> { … }
class ImpWrapper1<T> : Object, IWrapper<T> { … }
BUG: class ImpWrapper2 : Object, IWrapper<string> { … }
Generics declaration#
Some of the syntax could be best placed in the class/interface/struct pages, but that might overcomplicate them…
In class declaration - In struct declaration - In interface declaration - In base class declaration - In implemented interfaces declaration - In prerequesite class/interface declaration.
Declaration with type parameters introduces new types into that scope, identified by names given in declaration, e.g. T.
qualified-type-name-with-generic:qualified-class-name-with-genericqualified-interface-name-with-genericqualified-struct-name-with-genericqualified-class-name-with-generic:[ qualified-namespace-name . ] class-name type-parametersqualified-interface-name-with-generic:[ qualified-namespace-name . ] interface-name type-parametersqualified-struct-name-with-generic:[ qualified-namespace-name . ] struct-name type-parameterstype-parameters:< generic-clause >generic-clause:type-identifier [ , generic-clause ]qualified-type-name [ , generic-clause ]type-identifier:identifier
type-identifier will be the type-name for the parameterised type.
Deal is: in the class/interface/struct sections, replace qualified--name with qualified--name-with-generic.
Instantiation#
Only explanation here? Syntax should go with variable declaration statement?
When using generic for a type-name, only type-names can be used as type-parameters, not identifiers. NB. in scope of generic class, T etc. is a real type-name.
Examples#
Demonstrating…
1public interface With<T> {
2 public abstract void sett (T t);
3 public abstract T gett ();
4}
5
6public class One : Object, With<int> {
7 public int t;
8
9 public void sett (int t) {
10 this.t = t;
11 }
12 public int gett () {
13 return t;
14 }
15}
16
17public class Two<T,U> : Object, With<T> {
18 public T t;
19
20 public void sett (T t) {
21 this.t = t;
22 }
23 public T gett () {
24 return t;
25 }
26
27 public U u;
28}
29
30void main () {
31 var o = new One ();
32 o.sett (5);
33 stdout.printf ("%d\n", o.t);
34
35 var t = new Two<int,double?> ();
36 t.sett (5);
37 stdout.printf ("%d\n", t.t);
38
39 t.u = 5.0f;
40 stdout.printf ("%f\n", t.u);
41}