Frage

Es gibt nicht viele Informationen in der Spezifikation darüber, welcher Typ -Zuschreibung ist, und es gibt sicherlich nichts an dem Zweck dafür. Wofür würde ich abgesehen von "Durchgangsvarargs funktionieren", wofür ich einen Typ -Abruf verwenden würde? Unten finden Sie einige Scala -Replungen für die Syntax und die Auswirkungen der Verwendung.

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
War es hilfreich?

Lösung

Typ -Zuschreibung sagt dem Compiler nur, welchen Typ Sie von einem Ausdruck erwarten, von allen möglichen gültigen Typen.

Ein Typ ist gültig, wenn er vorhandene Einschränkungen respektiert, wie z. B. Varianz- und Typdeklarationen, und es ist entweder einer der Typen, auf den er gilt. "ist ein", oder es gibt eine Konvertierung, die im Umfang gilt.

So, java.lang.String extends java.lang.Object, deshalb alle String ist auch ein Object. In Ihrem Beispiel haben Sie erklärt, dass Sie den Ausdruck wollen s als ein behandelt werden Object, kein String. Da es keine Einschränkungen gibt, die dies verhindern und der gewünschte Typ einer der Typen ist s ist ein, Es klappt.

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 durch Typ -Aufschrift behoben haben können s bei ss Erklärung oder Sie hätten deklarieren können ssTyptyp zu sein Set[AnyRef].

Typ -Deklarationen erreichen jedoch nur so lange, wie Sie einem Kennung einen Wert zuweisen. Welches kann natürlich immer, wenn man den Code mit One-Shot-Kennungen nicht darum kümmert. Zum Beispiel wird das Folgende 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 albern, hier anstelle von einen Kennung zu verwenden Nil. Und obwohl ich einfach schreiben konnte List[String]() Stattdessen 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
}

Für die Referenz ist dies das, was Scala 2.7 Spec (15. März 2009) über die Typ -Zuschreibung zu sagen hat:

Expr1 ::= ...
        | PostfixExpr Ascription

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

Andere Tipps

Eine Möglichkeit besteht darin, wenn das Zeug für Netzwerk- und Serienprotokollebene, dann Folgendes folgendermaßen:

val x = 2 : Byte

ist weitaus sauberer als

val x = 2.asInstanceOf[Byte]

Die zweite Form ist auch eine Laufzeitumwandlung (nicht vom Compiler behandelt) und könnte zu interessanten Over/Under -Low -Bedingungen führen.

Ich verwende Typ -Zuschreibung zum Papier über Löchern in Scalas Typinferenz. Falten Sie beispielsweise über eine Sammlung vom Typ A ein anfängliches Element vom Typ B und eine Funktion (b, a) = B, mit der die Elemente der Sammlung in das Anfangselement falten. Der tatsächliche Wert des Typs B wird aus dem Typ des Anfangselements abgeleitet. Da NIL die Liste [nichts] erweitert, verursacht die Verwendung als ursprüngliches Element Probleme:

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)

Alternativ können Sie nur die Liste verwenden.

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

bearbeiten: list.eMpty [a] wird als implementiert als

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

(Quelle)

Dies ist effektiv eine ausführlichere Form von NIL: Liste [a

Du wirst vielleicht finden Dieser Thread Illuminierend, wenn auch etwas verwickelt, um zu folgen. Das Wichtigste ist zu beachten, dass Sie dem Typ -Checker Einschränkungen hinzufügen. Es gibt Ihnen etwas mehr Kontrolle darüber, was diese Kompilierungsphase tut.

Geben Sie Inferenz ein: Wir können explizit einen Namen von etwas im Quellcode geben, der als Typ -Inferenz bezeichnet wird (obwohl in einigen außergewöhnlichen Fällen erforderlich.)

Typenzuschreibung: Wenn Sie sich explizit über die Art von etwas befassen, wird als Typ -Zuschreibung bezeichnet. Welchen Unterschied kann es ausmachen?

Ex: Val x = 2: Byte

Siehe auch: 1. Wir können unseren Funktionen explizit Rückgabetyp geben

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

> t1: Option[Option[String]]

Eine andere Möglichkeit, dies zu erklären, könnte sein:

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

Hier gaben wir nicht Option[Option[String]] Rückgabetyp explizit und Compiler schließte ihn ab als Some[Option[String]]. Warum Some[Option[String]] liegt daran, dass wir in der Definition Typ -Zuschreibung verwendet haben.

  1. Eine andere Möglichkeit, die gleiche Definition zu verwenden, ist:

    def t3 = Some(None)

    > t3: Some[None.type]

Diesmal haben wir dem Compiler nichts explizit erzählt (weder dieser Defi). Und es leitete unsere Definition als einige [keine.typ

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top