Das Typsystem von Scala L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala 1 Eigenschaften Das Typsystem von Scala ist statisch, implizit und sicher L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala 2 Nichts Primitives Alles ist ein Objekt, es gibt keine primitiven Datentypen scala> 42.hashCode() res0: Int = 42 Der Datentyp ist hier Int Der Compiler entscheidet, ob der primitive Java-Typ int oder java.lang.Integer verwendet wird. L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala 3 Wozu primitive Datentypen? Auch in Java sind primitive Typen nicht unbedingt nötig. Alles kann mit Referenztypen ausgedrückt werden Schleife mit Laufvariable des primitiven Typs: for(int i=0; i<high; i++); Schleife mit Laufvariable der Hüllklasse: for(Integer i=0; i.compareTo(high)<0; i=i+1); L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala 4 Wozu primitive Datentypen? Da die Hüllklassen-Objekte unveränderbar sind, werden in der zweiten Schleife sehr viele Objekte erzeugt und irgendwann zerstört. Das ist bei primitiven Typen nicht der Fall! for(Integer i=0; i.compareTo(hi)<0; i=i+1); Primitive Typen sind ein Performance-Hack L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala 5 Der Compiler entscheidet Der Compiler entscheidet ähnlich wie wir: Immer wenn es möglich ̈ ist, wird int verwendet Nur dann, wenn es nötig ist, wird Integer benutzt. Übrigens: Bei Methoden mit maximal einem Parameter dürfen die Klammern fehlen: 42 hashCode Math sqrt 47.11 L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala 6 Vergleiche Anders als in Java entspricht der Operator == immer der Methode equals. Das folgende Codefragment liefert also true val i1: Int = 4711 val i2: Int = 4711 println(i1==i2) Referenzen vergleicht man so: val v1: java.lang.Integer = 42 val v2 = new java.lang.Integer(42) println(v1 eq v2) L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala 7 Wieder zwei Arten von Typen Nicht für alle Typen ist die Methode eq anwendbar: val i1 : Int =4711 val i2 : Int =4711 println(i1 eq i2) liefert eine Fehlermeldung, da Int auf den primitiven Typ int abgebildet werden kann. Scala unterscheidet zwei Arten von Typen Wertetypen Referenztypen L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala 8 Wertetypen Die Typen Unit (wird noch erklärt) Boolean Char Byte Short Int Long Float Double sind die Wertetypen L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala 9 Referenztypen Alle andere Typen sind Referenztypen. Basisklasse aller Referenztypen ist AnyRef Basisklasse aller Wertetypen ist AnyVal Basisklasse aller Typen ist Any AnyVal ist eine geschlossene Gesellschaft: Entwickler können selbst Referenztypen, aber keine Wertetypen definieren. L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala 10 Der Typ Unit Wir kennen in Java solche Definitionen void out(int v){ System.out.println("Hello Scala"); } Schön ist das nicht: void ist ein Schlüsselwort und kein Typ. Scala bietet hier wirklich einen eigenen Typ an: def out(v: Int): Unit = { println("Hello Scala") } Scala „bemüht“ sich mit einem Minimum von Schlüsselworten auszukommen! L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala 11 Der Typ Null Das einzige Objekt vom Typ Unit ist () scala> val u = () u: Unit = () Ebenso ist null kein Schlüsselwort, sondern das einzige Objekt vom Typ Null. Insbesondere ist Null Untertyp jedes Referenztypen scala> val nil = null nil: Null = null Das Schlüsselwort null entfällt so. L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala 12 Der Typ Nothing Der Typ Nothing ist Untertyp aller anderen Typen (bottom type). Es gibt keine Objekte vom Typ Nothing Der Typ Nothing ist gelegentlich sehr praktisch: Die leere Liste ist vom Typ List[Nothing] und kann somit jeder beliebigen Konstanten (Typ egal) zugewiesen werden. Scala-Typen als Graph: http://www.scala-lang.org/node/71 L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala 13 Typoperationen Typumwandlung (Java: Cast): Die generische Methode asInstanceOf[Typ] fasst ein Objekt als Objekt des angegebenen Typen auf: scala> v: Int Scala> Res17: val v = 7 = 7 v.asInstanceOf[Number] java.lang.Number = 7 Typtest (Java: instanceof): Die generische Methode isInstanceOf[Typ] testet, ob ein Objekt als Objekt des angegebenen Typen aufgefasst werden darf: scala> v: Int Scala> Res18: val v = 7 = 7 v.isInstanceOf[Number] Boolean = true L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala 14 Alles klar? Das Typsystem von Scala ist statisch, implizit und sicher. Der Basistyp aller Typen ist Any. In Scala ist jeder Wert ein Objekt. In Scala wird zwischen Wertetypen und Referenztypen unterschieden. Referenztypen sind Unterklassen von AnyRef. Anwender können selbst Klassen definieren. Es gibt neun Wertetypen in Scala. Alle Wertetypen sind Unterklassen von AnyVal. Alle Typen haben den gemeinsamen Untertypen Nothing. Alle Referenztypen haben den gemeinsamen Untertypen Null. Der Wertetyp Unit wird verwendet, um Funktionen zu definieren, die keinen Rückgabewert haben. L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala 15