Die Typzuweisung teilt dem Compiler lediglich mit, welchen Typ Sie von einem Ausdruck aus allen möglichen gültigen Typen erwarten.
Ein Typ ist gültig, wenn er vorhandene Einschränkungen wie Varianz- und Typdeklarationen berücksichtigt und entweder einer der Typen ist, auf die der Ausdruck " ist a " angewendet wird , oder wenn eine Konvertierung im Gültigkeitsbereich gilt.
Also, java.lang.String extends java.lang.Objectalso ist jeder Stringauch ein Object. In Ihrem Beispiel haben Sie angegeben, dass der Ausdruck sals Objectund nicht als behandelt werden soll String. Da dies durch keine Einschränkungen verhindert wird und der gewünschte Typ einer der Typen s ist , funktioniert a.
Warum willst du das? Bedenken Sie:
scala> val s = "Dave"
s: java.lang.String = Dave
scala> val p = s: Object
p: java.lang.Object = Dave
scala> val ss = scala.collection.mutable.Set(s)
ss: scala.collection.mutable.Set[java.lang.String] = Set(Dave)
scala> val ps = scala.collection.mutable.Set(p)
ps: scala.collection.mutable.Set[java.lang.Object] = Set(Dave)
scala> ss += Nil
<console>:7: error: type mismatch;
found : scala.collection.immutable.Nil.type (with underlying type object Nil)
required: java.lang.String
ss += Nil
^
scala> ps += Nil
res3: ps.type = Set(List(), Dave)
Sie hätten dies auch beheben können, indem Sie sbei der ssDeklaration ascripting eingeben, oder Sie hätten den ssTyp deklarieren können Set[AnyRef].
Typdeklarationen erreichen jedoch nur dasselbe, solange Sie einem Bezeichner einen Wert zuweisen. Was man natürlich immer tun kann, wenn man den Code nicht mit One-Shot-Identifikatoren übersät. Folgendes wird beispielsweise nicht kompiliert:
def prefixesOf(s: String) = s.foldLeft(Nil) {
case (head :: tail, char) => (head + char) :: head :: tail
case (lst, char) => char.toString :: lst
}
Aber das tut:
def prefixesOf(s: String) = s.foldLeft(Nil: List[String]) {
case (head :: tail, char) => (head + char) :: head :: tail
case (lst, char) => char.toString :: lst
}
Es wäre dumm, hier anstelle von einen Bezeichner zu verwenden Nil. Und obwohl ich List[String]()stattdessen einfach schreiben könnte , ist das nicht immer eine Option. Betrachten Sie dies zum Beispiel:
def firstVowel(s: String) = s.foldLeft(None: Option[Char]) {
case (None, char) => if ("aeiou" contains char.toLower) Some(char) else None
case (vowel, _) => vowel
}
Als Referenz ist dies, was Scala 2.7 spec (Entwurf vom 15. März 2009) über die Typzuweisung zu sagen hat:
Expr1 ::= ...
| PostfixExpr Ascription
Ascription ::= ‘:’ InfixType
| ‘:’ Annotation {Annotation}
| ‘:’ ‘_’ ‘*’