如何处理在Scala中返回具有泛型类型的对象的函数

时间:2015-08-21 22:14:28

标签: scala generics typeclass static-typing

这是我想要完成的事情的简化示例。我有一个函数,根据传递给它的Field对象的类型,生成不同签名的HashMap。我不确定解决这个问题的最佳方法是什么。任何帮助表示赞赏。

trait Field
case class IntField extends Field {
    def convert(x: String): Int = x.toInt
}
case class StringField extends Field {
    def convert(x: String): String = x
}
case class DoubleField etc...

def someFunc(field: Field): HashMap[?, Int] = {
    val index = new HashMap[?, Int]() // This needs to be [String, Int] or [Int, Int] or [Double, Int]

    val data = // some data from csv file that will be parsed

    for (line <- data) {
        val values = field.convert(data) // can return String or Int or Double
        index.put(values, 0)       
    }
    index
}

1 个答案:

答案 0 :(得分:3)

你应该能够通过向Field trait添加一个类型参数来实现这一点(我添加了HashMap导入并将数据显式设置为“123”以便能够在REPL中测试它):

trait Field[A] {
    def convert(x: String): A // Need to define convert for the trait, too.
}
case class IntField extends Field[Int] {
    def convert(x: String): Int = x.toInt
}
case class StringField extends Field[String] {
    def convert(x: String): String = x
}
//case class DoubleField etc...

import scala.collection.mutable.HashMap
def someFunc[A](field: Field[A]): HashMap[A, Int] = {
    val index = new HashMap[A, Int]() // This needs to be [String, Int] or [Int, Int] or [Double, Int]

    val data = "123"// some data from csv file that will be parsed

    for (line <- data) {
        val values = field.convert(data) // can return String or Int or Double
        index.put(values, 0)
    }
    index
}

现在调用someFunc将确定传入字段中的类型并生成适当类型的HashMap:

scala> someFunc(IntField())
res1: scala.collection.mutable.HashMap[Int,Int] = Map(123 -> 0)

scala> :t res1
scala.collection.mutable.HashMap[Int,Int]

scala> someFunc(StringField())
res2: scala.collection.mutable.HashMap[String,Int] = Map(123 -> 0)

scala> :t res2
scala.collection.mutable.HashMap[String,Int]