Учитывая следующий кодПонимание экзистенциальные типы в Scala
import scala.collection.mutable.Set
import scala.collection.mutable.HashMap
// classes to create field types that do conversion of string to other types
trait Field[A] {
def convert(x: String): A // Need to define convert for the trait, too.
}
case class IntField extends Field[Int] {
override def convert(x: String): Int = x.toInt
}
case class StringField extends Field[String] {
override def convert(x: String): String = x
}
// this function can take any Field type and return a HashMap,
// more important here is type of key not the value of HashMap
// which has to match with value returned from Field.convert()
def someFunc[A](field: Field[A]): HashMap[A, Int] = {
val index = new HashMap[A, Int]()
val data = List("111", "222", "333")
for (line <- data) {
val values: A = field.convert(line)
index.put(values, 0)
}
index
}
// this empty set will be populated with Field objects, and here I get an error
var fields = Set[Field[A]]()
def addField[A](field: Field[A]): Unit = fields += field
addField(StringField())
addField(IntField())
for (field <- fields) println(someFunc(field))
// RESULT
Map(333 -> 0, 222 -> 0, 111 -> 0) // HashMap[String, Int]
Map(111 -> 0, 333 -> 0, 222 -> 0) // HashMap[Int, Int]
Выше не будет компилировать, ошибка not found: type A
при создании var fields
-. Теперь, когда я изменить эту строку следующим образом:
var fields = Set[Field[A] forSome {type A}]()
Все компилируется, но я не совсем понимаю, что здесь происходит. Я понимаю, что при выполнении var fields = Set[Field[A]]()
типа A не существует, но как другая строка исправляет эту проблему и является ли она правильным решением или просто работает в этом случае?
Если я просто объявить 'типа Ā' в верхней части коды и использовать' вар fields = Set [Field [A]]() 'он все равно не будет компилироваться. Это потому, что 'Поле [A] forSome {type A}' создает 'тип A' в контексте' Field [A] '? Если это имеет смысл. –
Если вы объявляете такой тип: type A = Field [B] forSome {type B}, он будет скомпилирован, поэтому A forSome {type A} - это просто специальная конструкция scala, которая позволяет создавать экзистенциальные типы, которые являются способом сказать что это может быть любой тип – grotrianster