import std.io;
fn Id(x: T): T { return x; }
fn Pair(a: A, b: B): A { return a; }
fn main(): int64 {
PrintLn(IntToStr(Id(42))); // 42
PrintLn(IntToStr(Pair(7, 9))); // 7
return 0;
}
Der Typ lässt sich auch ausdrücklich angeben, etwa für Structs:
type P = struct { x: int64; };
fn main(): int64 {
var p: P;
p.x := 5;
var q: P := Id(p);
PrintLn(IntToStr(q.x)); // 5
return 0;
}
Ein Typparameter darf innerhalb der Funktion an einen weiteren generischen Aufruf weitergereicht werden:
fn Zweimal(x: T): T { return Id(x); }
* Ein Typparameter gilt nur **innerhalb** seiner Funktion.
* Mehrere Parameter werden mit Komma getrennt: ''fn Pair<A, B>''.
* Die eckige Schreibweise ''%%Id[T]%%'' gibt es nicht — der Parser erwartet spitze Klammern.
import std.io;
type Zeichenbar = interface {
fn Flaeche(): int64;
};
type Kreis = class implements Zeichenbar {
r: int64;
fn Flaeche(): int64 { return self.r * self.r; }
};
fn main(): int64 {
var k: Kreis := new Kreis();
k.r := 4;
PrintLn(IntToStr(k.Flaeche())); // 16
return 0;
}
**Die Verpflichtung wird geprüft:** Fehlt eine Methode, meldet der Compiler ''class missing interface method''. Das ist der eigentliche Gewinn — die Schnittstelle ist nicht bloß Dokumentation.
==== Als Parametertyp ====
Der Interface-Name taugt als Typ. Damit lässt sich eine Funktion schreiben, die jede implementierende Klasse annimmt:
unit main;
import std.io;
import std.string;
type Zeichenbar = interface {
fn Flaeche(): int64;
};
type Kreis = class implements Zeichenbar {
r: int64;
fn Flaeche(): int64 { return self.r * self.r; }
};
type Quadrat = class implements Zeichenbar {
s: int64;
fn Flaeche(): int64 { return self.s * self.s; }
};
fn Zeige(z: Zeichenbar): int64 { return z.Flaeche(); }
fn main(): int64 {
var k: Kreis := new Kreis(); k.r := 3;
var q: Quadrat := new Quadrat(); q.s := 5;
PrintLn(IntToStr(Zeige(k))); // 9
PrintLn(IntToStr(Zeige(q))); // 25
return 0;
}
9
25
Der Aufruf über den Interface-Typ trifft die richtige Implementierung — das war bis lyxc 1.0.14 nicht der Fall ([[https://github.com/SEOLizer/LyX-Compiler/issues/1133|Issue #1133]]).
==== Mehrere Interfaces ====
type Lesbar = interface { fn Lies(): int64; };
type Schreibbar = interface { fn Schreib(v: int64): int64; };
type Datei = class implements Lesbar, Schreibbar {
wert: int64;
fn Lies(): int64 { return self.wert; }
fn Schreib(v: int64): int64 { self.wert := v; return 0; }
};
==== Was Interfaces nicht können ====
^ Konstrukt ^ Verhalten ^
| ''%%type S = struct implements I%%'' | abgewiesen — nur Klassen können ''implements'' tragen |
| ''%%type B = interface extends A%%'' | abgewiesen — keine Interface-Vererbung |
| Methodenrumpf im Interface | die Klasse muss die Methode dennoch selbst mitbringen; eine Standardimplementierung entsteht daraus nicht |
----
===== 3. Typbedingungen =====