Type de nom est juste de dire au compilateur quel type que vous attendez d'une expression, contre tous les types valides.
Un type est valide s'il respecte les contraintes existantes, telles que la variance et les déclarations de type, et il est l'un des types de l'expression qu'il s'applique "est un", ou il y a une conversion qui s'applique dans le champ d'application.
Donc, java.lang.String extends java.lang.Object
, par conséquent, toute String
est aussi un Object
. Dans votre exemple, vous avez déclaré que vous voulez l'expression s
à être traité comme un Object
, pas un String
. Depuis il n'y a pas de contraintes la prévention et le type est l'un des types s
est un, il fonctionne.
Maintenant, pourquoi voudriez-vous que? Réfléchissez à ceci:
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)
Vous pourriez aussi avoir résolu ce par type ascripting s
à ss
déclaration, ou vous pourriez avoir déclaré ss
s'type Set[AnyRef]
.
Cependant, les déclarations de type de réaliser la même chose aussi longtemps que vous assignez une valeur à un identificateur. De laquelle on peut toujours le faire, bien sûr, si l'on ne se soucie pas encombrer le code avec one-shot identifiants. Pour exemple, le code suivant ne compile pas:
def prefixesOf(s: String) = s.foldLeft(Nil) {
case (head :: tail, char) => (head + char) :: head :: tail
case (lst, char) => char.toString :: lst
}
Mais ce n':
def prefixesOf(s: String) = s.foldLeft(Nil: List[String]) {
case (head :: tail, char) => (head + char) :: head :: tail
case (lst, char) => char.toString :: lst
}
Il serait stupide d'utiliser un identificateur ici à la place de Nil
. Et si seulement je pouvais écrire List[String]()
au lieu de cela, ce n'est pas toujours une option. Considérez ceci, par exemple:
def firstVowel(s: String) = s.foldLeft(None: Option[Char]) {
case (None, char) => if ("aeiou" contains char.toLower) Some(char) else None
case (vowel, _) => vowel
}
Pour la référence, c'est ce que Scala de 2,7 spec (15 mars 2009 projet) a à dire sur le type de nom:
Expr1 ::= ...
| PostfixExpr Ascription
Ascription ::= ‘:' InfixType
| ‘:' Annotation {Annotation}
| ‘:' ‘_' ‘*'