Какова цель типовых надписей в Scala?

В спецификации не так много информации о том, что такое начертание типа, и, конечно же, там нет ничего о его назначении. За исключением того, что "заставляю прохождение varargs работать", для чего я буду использовать типовое обозначение? Ниже приведен некоторый scala REPL для синтаксиса и последствий его использования.

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

5 ответов

Решение

Тип ascription просто сообщает компилятору, какой тип вы ожидаете от выражения, от всех возможных допустимых типов.

Тип действителен, если он учитывает существующие ограничения, такие как объявления отклонений и типов, и это либо один из типов, к которым выражение, к которому он применяется, относится ктипу"is a", либо существует преобразование, которое применяется в области видимости.

Так, java.lang.String extends java.lang.Objectпоэтому любой String также Object, В вашем примере вы объявили, что хотите выражение sрассматриваться как Object неString, Поскольку нет никаких препятствий, препятствующих этому, и желаемый тип является одним из типовsэто работает.

Теперь, почему вы хотите этого? Учти это:

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)

Вы также могли бы исправить это по типу ascripting s в ss декларация, или вы могли бы заявить ssтип быть Set[AnyRef],

Однако объявления типов достигают того же самого, только если вы присваиваете значение идентификатору. Что всегда можно сделать, если, конечно, не нужно засорять код одноразовыми идентификаторами. Например, следующее не компилируется:

def prefixesOf(s: String) = s.foldLeft(Nil) { 
  case (head :: tail, char) => (head + char) :: head :: tail
  case (lst, char) => char.toString :: lst
}

Но это делает:

def prefixesOf(s: String) = s.foldLeft(Nil: List[String]) { 
  case (head :: tail, char) => (head + char) :: head :: tail
  case (lst, char) => char.toString :: lst
}

Было бы глупо использовать идентификатор здесь вместо Nil, И хотя я мог бы просто написать List[String]() напротив, это не всегда вариант. Рассмотрим это, например:

def firstVowel(s: String) = s.foldLeft(None: Option[Char]) { 
  case (None, char) => if ("aeiou" contains char.toLower) Some(char) else None
  case (vowel, _) => vowel
}

Для справки, вот что спецификация Scala 2.7 (черновик 15 марта 2009 г.) должна сказать о типе ascription:

Expr1 ::= ...
        | PostfixExpr Ascription

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

Одна возможность, когда уровень сетевого и последовательного протоколов, то это:

val x = 2 : Byte

намного чище, чем

val x = 2.asInstanceOf[Byte]

Вторая форма также является преобразованием во время выполнения (не обрабатывается компилятором) и может привести к некоторым интересным условиям переполнения / переполнения.

Вы можете найти эту ветку осветительной, если немного усложнены. Важно отметить, что вы добавляете подсказки ограничений в средство проверки типов - это дает вам немного больше контроля над тем, что делает эта фаза компиляции.

Вывод типа: мы можем пропустить явное указание имени типа чего-либо в исходном коде, называемого выводом типа (хотя требуется в некоторых исключительных случаях).

Тип Ascription: Быть явным в отношении типа чего-либо называется Type Ascription. Какая разница это может иметь?

например: val x = 2: байт

см. также: 1. Мы можем явно указать тип возвращаемого значения для наших функций.

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

> t1: Option[Option[String]]

Другой способ объявить это может быть:

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

Здесь мы не дали Option[Option[String]] возвращаемый тип явно, и компилятор выводит его как Some[Option[String]], Зачем Some[Option[String]] потому что мы использовали определение типа в определении.

  1. Другой способ, которым мы можем использовать то же определение:

    def t3 = Some(None)

    > t3: Some[None.type]

На этот раз мы ничего явно не сказали компилятору (ни это определение). И это вывело наше определение как Некоторые [None.type]

Я использую типовое обозначение для бумаги над отверстиями в логическом выводе Scala. Например, foldLeft над коллекцией типа A берет начальный элемент типа B и функцию (B, A) => B, которая используется для свертывания элементов коллекции в начальный элемент. Фактическое значение типа B выводится из типа исходного элемента. Поскольку Nil расширяет List[Nothing], использование его в качестве исходного элемента вызывает проблемы:

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)

В качестве альтернативы вы можете просто использовать List.empty[Int] вместо Nil:List[Int].

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

редактировать: List.empty[A] реализован как

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

(источник)

Это фактически более многословная форма Nil:List[A]

Другие вопросы по тегам