Вопрос

В спецификации не так много информации о том, что такое тип, и там, конечно, нет ничего об этой цели. Помимо «заставляя работать прохождение варарг», для чего я использовал тип подписания? Ниже приведена некоторая 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
Это было полезно?

Решение

Тип 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 Spec (Draft 15 марта 2009 г.) говорит о типе подписания:

Expr1 ::= ...
        | PostfixExpr Ascription

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

Другие советы

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

val x = 2 : Byte

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

val x = 2.asInstanceOf[Byte]

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

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

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] вместо нуля: 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

(источник)

Это фактически более многословная форма нуля: список [a

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

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

Тип подписания: четко явное о типе чего -то называется типом. Какую разницу это может сделать?

Пример: 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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top