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.Object
also ist jeder String
auch ein Object
. In Ihrem Beispiel haben Sie angegeben, dass der Ausdruck s
als Object
und 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 s
bei der ss
Deklaration ascripting eingeben, oder Sie hätten den ss
Typ 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}
| ‘:’ ‘_’ ‘*’