Ich habe gehört, dass Scala pfadabhängige Typen hat. Es hat etwas mit Innenklassen zu tun, aber was bedeutet das eigentlich und warum kümmert es mich?
Ich habe gehört, dass Scala pfadabhängige Typen hat. Es hat etwas mit Innenklassen zu tun, aber was bedeutet das eigentlich und warum kümmert es mich?
Antworten:
Mein Lieblingsbeispiel:
case class Board(length: Int, height: Int) {
case class Coordinate(x: Int, y: Int) {
require(0 <= x && x < length && 0 <= y && y < height)
}
val occupied = scala.collection.mutable.Set[Coordinate]()
}
val b1 = Board(20, 20)
val b2 = Board(30, 30)
val c1 = b1.Coordinate(15, 15)
val c2 = b2.Coordinate(25, 25)
b1.occupied += c1
b2.occupied += c2
// Next line doesn't compile
b1.occupied += c2
Die Art von Coordinate
hängt also von der Instanz ab, Board
von der es instanziiert wurde. Es gibt alle möglichen Dinge, die damit erreicht werden können und eine Art Typensicherheit bieten, die von Werten und nicht nur von Typen abhängt.
Dies mag nach abhängigen Typen klingen, ist jedoch eingeschränkter. Zum Beispiel ist der Typ von occupied
abhängig vom Wert von Board
. Oben funktioniert die letzte Zeile nicht, weil der Typ von c2
ist b2.Coordinate
, während occupied
der Typ ist Set[b1.Coordinate]
. Beachten Sie, dass ein anderer Bezeichner mit demselben Typ von verwendet werden kann b1
, sodass dem Typ nicht der Bezeichner zugeordnet b1
ist. Zum Beispiel funktioniert Folgendes:
val b3: b1.type = b1
val c3 = b3.Coordinate(10, 10)
b1.occupied += c3