Pregunta

No hay mucha información en la especificación de qué tipo es adscripción, y ciertamente no hay nada allí sobre el propósito para ello. Aparte de "hacer pasar el trabajo varargs", lo que iba a utilizar el tipo de adscripción? A continuación se ofrece REPL Scala para la sintaxis y los efectos de su uso.

scala> val s = "Dave"
s: java.lang.String = Dave

scala> val p = s:Object
p: java.lang.Object = Dave

scala> p.length
<console>:7: error: value length is not a member of java.lang.Object
       p.length
         ^
scala> p.getClass
res10: java.lang.Class[_ <: java.lang.Object] = class java.lang.String

scala> s.getClass
res11: java.lang.Class[_ <: java.lang.Object] = class java.lang.String

scala> p.asInstanceOf[String].length
res9: Int = 4
¿Fue útil?

Solución

Tipo de adscripción es simplemente indica al compilador qué tipo usted espera de una expresión, de todos los posibles tipos válidos.

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 refiere a: " es un ", o hay una conversión que se aplica en su alcance.

Así, java.lang.String extends java.lang.Object, por lo tanto cualquier String es también un Object. En su ejemplo usted declaró que desea que el s expresión a ser tratado como un Object, no un String. Puesto que no hay limitaciones que impiden que el tipo deseado y es uno de los tipos s es un , funciona.

Ahora, ¿por qué quieres eso? Considere lo siguiente:

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 s ascripting en la declaración ss, o que podría haber declarado tipo de ss ser Set[AnyRef].

Sin embargo, declaraciones de tipo lograr lo mismo sólo el tiempo que va a asignar un valor a un identificador. Los cuales siempre se puede hacer, por supuesto, si uno no se preocupan por ensuciar el código con los identificadores de un solo disparo. 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
}

Sin embargo, 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 a pesar de que sólo podía escribir List[String]() lugar, eso no es siempre 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}
             | ‘:’ ‘_’ ‘*’

Otros consejos

Una posibilidad es cuando la red y cosas por nivel de protocolo en serie, entonces esto:

val x = 2 : Byte

es mucho más limpio que

val x = 2.asInstanceOf[Byte]

La segunda forma es también una conversión de tiempo de ejecución (no se maneja por el compilador) y podría conducir a algunas condiciones interesantes más / subdesbordamiento.

Yo uso Tipo de adscripción de tapar agujeros en la inferencia de tipos de Scala. Por ejemplo, foldLeft sobre una colección de tipo A toma un elemento inicial de tipo B y una función (B, A) => B que se utiliza para doblar los elementos de la colección en el elemento inicial. El valor real de tipo B se infiere a partir del tipo del elemento inicial. Desde Cero extiende Lista [Nada], utilizando como elemento inicial provoca problemas:

scala> val x = List(1,2,3,4)
x: List[Int] = List(1, 2, 3, 4)

scala> x.foldLeft(Nil)( (acc,elem) => elem::acc)
<console>:9: error: type mismatch;
 found   : List[Int]
 required: scala.collection.immutable.Nil.type
              x.foldLeft(Nil)( (acc,elem) => elem::acc)
                                                 ^

scala> x.foldLeft(Nil:List[Int])( (acc,elem) => elem::acc )
res2: List[Int] = List(4, 3, 2, 1)

Como alternativa, es posible que utilices List.empty [Int] en lugar de Cero:. Lista [Int]

scala> x.foldLeft(List.empty[Int])( (acc,elem) => elem::acc )
res3: List[Int] = List(4, 3, 2, 1)

edit: List.empty [A] se implementa como

override def empty[A]: List[A] = Nil

(fuente )

Esto es efectivamente una forma más detallado de Cero: Lista [A]

Usted puede encontrar este hilo iluminando, si un poco complicado de seguir. Lo importante a destacar es que va a añadir a la restricción insinúa comprobador de tipos -. Le da un poco más de control sobre lo que está haciendo fase de compilación

Inferencia: Podemos omitir explícitamente dando Nombre de Tipo de Algo en código fuente, llamada Inferencia de tipos

. (Aunque se requiere en algunos casos excepcionales).

Tipo Adscripción: Ser explícito sobre el tipo de algo se llama una indicación de tipo. Lo que diferencia que puede hacer?

ex: val x = 2: Byte

También ver: 1. Podemos dar explícitamente el tipo de retorno a nuestras funciones

def t1 : Option[Option[String]] = Some(None)

> t1: Option[Option[String]]

Otra manera de declarar esto podría ser:

def t2 = Some(None: Option[String])
> t2: Some[Option[String]]

Aquí no nos damos vuelta Option[Option[String]] tipo de forma explícita y compilador inferimos como Some[Option[String]]. ¿Por Some[Option[String]] es porque utilizamos tipo adscripción en la definición.

  1. Otra manera en que podemos utilizar la misma definición es:

    def t3 = Some(None)

    > t3: Some[None.type]

Esta vez no le dijo nada explícitamente el compilador (ni esta defi). Se infiere y nuestra definición como algunos [None.type]

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top