[英]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.