Traits
Als Trait deklarieren, was ein Typ kann, ihn einem Typ jetzt oder später geben und den Trait als Typ benutzen, der jeden davon hält.
Es gibt keine Klassen und keine Vererbung. Was ein Typ kann, ist ein Trait, ähnlich einem Interface oder einem Protocol.
Ziel#
Am Ende dieser Seite kannst du einen Trait deklarieren, ihn einem Typ geben und den Trait als Typ benutzen.
Einen Trait deklarieren und einem Typ geben#
trait Shape {
fn area(): Float
fn describe(): String {
"area {area()}"
}
}
type Square with Shape {
side: Float
fn area(): Float {
side * side
}
}
print Square(2.0).describe()
// prints area 4.0area hat keinen Rumpf, also muss jeder Typ with Shape einen schreiben. describe hat einen Rumpf, also bekommt
Square ihn gratis. Ein Trait mit einer Methode heißt wie diese Methode: Hash, Equals, Show, nie Hashable.
Später geben mit extend#
trait Shape {
fn area(): Float
}
type Circle {
radius: Float
}
extend Circle with Shape {
fn area(): Float {
3.0 * radius * radius
}
}
const shapes: List<Shape> = [Circle(1.0)]
for shape in shapes {
print shape.area()
}
// prints 3.0extend gibt einem Typ, den es schon gibt, einen Trait, sogar einem aus der Standardbibliothek. Ein Trait funktioniert
als Typ: List<Shape> hält jeden Wert, dessen Typ Shape hat. Darüber kannst du nur aufrufen, was Shape
deklariert.
Operatoren sind Traits#
type Vector with Add {
x: Int
y: Int
fn add(other: Vector): Vector {
Vector(x + other.x, y + other.y)
}
}
print(Vector(1, 2) + Vector(3, 4))
// prints Vector(x: 4, y: 6)+ ruft add des Traits Add auf, == ruft equals von Equals auf, und < ruft compare von Compare auf. Ein
Typ bekommt einen Operator, indem er dessen Trait hat.
Weiter#
- Fehler - wie eine Funktion sagt, dass sie scheitern kann.
- Traits - die genauen Regeln.
- Operators are traits - jeder Operator und sein Trait.