La asignación de tipo solo le dice al compilador qué tipo espera de una expresión, de todos los tipos válidos posibles.
Un tipo es válido si respeta las limitaciones existentes, tales como la varianza y declaraciones de tipo, y es uno cualquiera de los tipos de la expresión se aplica a "es una", o hay una conversión que se aplica en su alcance.
Por lo tanto, java.lang.String extends java.lang.Object
, por lo tanto cualquier String
es también un Object
. En su ejemplo, declaró que desea que la expresión s
se trate como Object
, no como String
. Como no hay restricciones que lo impidan y el tipo deseado es uno de los tipos s
es, funciona.
Ahora, ¿por qué querrías eso? Considere esto:
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)
También podría haber solucionado este tipo por ascripting s
en ss
declaración, o que podría haber declarado ss
's Tipo ser Set[AnyRef]
.
Sin embargo, las declaraciones de tipo solo logran lo mismo siempre que asigne un valor a un identificador. Lo que uno siempre puede hacer, por supuesto, si a uno no le importa tirar el código con identificadores de un solo uso. Por ejemplo, lo siguiente no se compila:
def prefixesOf(s: String) = s.foldLeft(Nil) {
case (head :: tail, char) => (head + char) :: head :: tail
case (lst, char) => char.toString :: lst
}
Pero esto hace:
def prefixesOf(s: String) = s.foldLeft(Nil: List[String]) {
case (head :: tail, char) => (head + char) :: head :: tail
case (lst, char) => char.toString :: lst
}
Sería tonto para usar un identificador de aquí en lugar de Nil
. Y aunque solo podía escribir List[String]()
, eso no siempre es una opción. Considere esto, por ejemplo:
def firstVowel(s: String) = s.foldLeft(None: Option[Char]) {
case (None, char) => if ("aeiou" contains char.toLower) Some(char) else None
case (vowel, _) => vowel
}
Para la referencia, esto es lo Scala 2.7 spec (Marzo 15, 2009 PROYECTO) tiene que decir sobre el tipo de adscripción:
Expr1 ::= ...
| PostfixExpr Ascription
Ascription ::= ‘:’ InfixType
| ‘:’ Annotation {Annotation}
| ‘:’ ‘_’ ‘*’
Heh, aprendí algo nuevo. Hago una cantidad desafortunada de cosas del protocolo de red. ¡Bueno saber! –
¿Por qué no utilizar la sintaxis diaria? 'val x: Byte = 2' – Jerry101