Какова цель типовых надписей в Scala? - PullRequest
70 голосов
/ 18 января 2010

В спецификации не так много информации о том, что это за тип, и, конечно же, там нет ничего о его назначении. Кроме того, чтобы "сделать прохождение 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 ]

73 голосов
/ 18 января 2010

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

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

Итак, 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)

Вы могли бы также исправить это, указав тип 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}
             | ‘:’ ‘_’ ‘*’
27 голосов
/ 18 января 2010

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

val x = 2 : Byte

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

val x = 2.asInstanceOf[Byte]

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

0 голосов
/ 02 июня 2017

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

Приписывание типа: явное указание на тип чего-либоназывается типом приписки.Какая разница?

ex: 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]] потому что мы использовали определение типа в определении.

Другой способ использовать то же определение:

def t3 = Some(None)

> t3: Some[None.type]

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

0 голосов
/ 02 апреля 2014

Я использую типовое обозначение для бумаги над отверстиями в логическом выводе 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)

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

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

(источник)

Это, по сути, более многословная форма Nil: Список [A]

0 голосов
/ 21 января 2010

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

...