Question

Il n'y a pas beaucoup d'infos dans les spécifications de ce type est ascription, et il n'y a certainement rien là-dedans sur le but pour elle. Autre que « faire passer le travail varargs », qu'est-ce que j'utiliser le type ascription pour? Ci-dessous quelques REPL scala pour la syntaxe et les effets de l'utiliser.

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
Était-ce utile?

La solution

Type ascription est tout simplement dire au compilateur quel type vous attendez d'une expression, de tous les types possibles valides.

Un type est valide si elle respecte les contraintes existantes, telles que les déclarations de la variance et le type, et il est l'un des types l'expression qu'il applique à « est un », ou il y a une conversion applique une portée.

Alors, java.lang.String extends java.lang.Object donc tout String est aussi un Object. Dans votre exemple, vous avez déclaré que vous voulez que le s d'expression à traiter comme un Object, pas String. Comme il n'y a pas de contraintes qui empêchent et le type désiré est l'un des types s est un , cela fonctionne.

Maintenant, pourquoi voudriez-vous que? Considérez 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 pouvez également avoir résolu cela, ou vous pourriez avoir déclaré par type ascripting s à déclaration ss type de ss à Set[AnyRef].

Toutefois, les déclarations de type atteignent la même chose aussi longtemps que vous attribuez une valeur à un identifiant. Lequel peut toujours faire, bien sûr, si l'on ne se soucie pas de jeter des ordures le code avec des identifiants d'un coup. Par exemple, ce qui suit 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 cela ne:

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 identifiant ici à la place de Nil. Et si je pouvais écrire juste List[String]() à la place, 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 2.7 spec (15 mars 2009 projet) a à dire sur le type ascription:

Expr1 ::= ...
        | PostfixExpr Ascription

Ascription ::= ‘:’ InfixType
             | ‘:’ Annotation {Annotation}
             | ‘:’ ‘_’ ‘*’

Autres conseils

Il est possible lorsque le réseau et d'autres choses série de niveau de protocole, alors ceci:

val x = 2 : Byte

est beaucoup plus propre que

val x = 2.asInstanceOf[Byte]

La deuxième forme est également une conversion d'exécution (non géré par le compilateur) et pourrait conduire à des conditions plus / sousverse intéressantes.

J'utilise le type de papier sur ascription trous dans l'inférence de type Scala. Par exemple, foldLeft sur une collection de type A a un premier élément de type B et une fonction (B, A) => B qui est utilisé pour plier les éléments de la collection dans l'élément initial. La valeur réelle de type B est déduit du type de l'élément initial. Depuis Nil étend la liste [Rien], en utilisant comme un élément initial pose des problèmes:

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)

Vous pouvez simplement utiliser List.empty [Int] au lieu de Néant.: Liste [Int]

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

edit: List.empty [A] est mis en œuvre sous la forme

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

(source )

Ceci est effectivement une forme plus détaillée de Nil: Liste [A]

Vous pouvez trouver ce fil d'éclairage, si un peu alambiquée à suivre. La chose importante à noter est que vous ajoutez la contrainte des suggestions à type vérificateur -. Il vous donne un peu plus de contrôle sur ce que la phase de compilation fait

Type Inference: Nous pouvons sauter Explicitement donner Nom de type de quelque chose dans le code source, appelé Inférence de type

. (Même si nécessaire dans certains cas exceptionnels.)

Type L'imputation: Être explicite sur le type de quelque chose est appelé Type une indication. Quelle différence Il peut faire?

ex: val x = 2: Octet

voir aussi: 1. On peut donner explicitement le type de retour à nos fonctions

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

> t1: Option[Option[String]]

Une autre façon de déclarer cela pourrait être:

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

Ici, nous n'avons pas donné le type de retour de Option[Option[String]] explicitement et du compilateur inféré comme il Some[Option[String]]. Pourquoi Some[Option[String]] est parce que nous avons utilisé le type ascription dans la définition.

  1. Une autre façon que nous pouvons utiliser la même définition est:

    def t3 = Some(None)

    > t3: Some[None.type]

Cette fois, nous ne dit pas explicitement quoi que ce soit du compilateur (ni ce defi). Il en a déduit et notre définition comme certains [None.type]

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top