[英]Understanding existential types in 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
錯誤not found: type A
創建var fields
時not found: type A
。 現在,當我將這一行更改為:
var fields = Set[Field[A] forSome {type A}]()
一切都可以編譯,但是我不完全了解這里會發生什么。 我了解執行var fields = Set[Field[A]]()
不存在類型A,但是其他行如何解決此問題,它甚至是正確的解決方案,還是恰好在這種情況下起作用?
Field[A] forSome {type A}
-您可以將A用作類型(參數化類型為A的參數字段),因為在大括號中聲明了該類型,存在性類型是一種表示您可以接受任何類型的方式當方法addField為參數時,將Seq [Field]與存在類型一起使用是一種解決方案,因為此集合將存儲不同的類型。
您的問題可能不是真正存在的類型,而是泛型的定義和用法,因為var fields = A
也不會編譯。
在
var fields = Set[Field[A]]()
A
未定義,因為您沒有在范圍內的任何地方聲明它。
在
trait Field[A] {
def someFunc[A](field: Field[A]): HashMap[A, Int] = {
def addField[A](field: Field[A]): Unit = fields += field
A聲明為類型參數,即將按用途定義。
當你把兩只StringField
和IntField
在你的fields
變種,我想你想的字段是一個Set
任何類型的Field
。 因此,通常您通過通配符告訴編譯器:
var fields = Set[Field[_]]()
這本質上是寫作的捷徑
var fields = Set[Field[A] forSome {type A}]()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.