Scala泛型类型方法匹配

时间:2018-01-08 07:47:48

标签: scala generics

我正在构建一个Scala泛型类型方法,它采用不同大小的元组并输出一行CSV字符串。我写的代码就像这样

object CSVFormat {
  protected def valueToCSV[T](value: Seq[T]): String =
    s""""${value.map(_.toString).mkString("{", ",", "}")}""""
  protected def valueToCSV[T](value: T): String =
    s""""${value.toString}""""

  def rowToCSV[A](row: (A)): String = valueToCSV(row)
  def rowToCSV[A, B](row: (A, B)): String =
    s"${rowToCSV((row._1))},${rowToCSV((row._2))}"
  def rowToCSV[A, B, C](row: (A, B, C)): String =
    s"${rowToCSV((row._1, row._2))},${rowToCSV((row._3))}"
  def rowToCSV[A, B, C, D](row: (A, B, C, D)): String =
    s"${rowToCSV((row._1, row._2, row._3))},${rowToCSV((row._4))}"
  def rowToCSV[A, B, C, D, E](row: (A, B, C, D, E)): String =
    s"${rowToCSV((row._1, row._2, row._3, row._4))},${rowToCSV((row._5))}"
}

我想要得到的是像

CSVFormat.rowToCSV(("hello", 1234, Seq("a", "b", "c")))

然后输出应该是

"hello","1234","{a,b,c}"

这里的主要问题是Seq[T]类型匹配和T方法的valueToCSV类型匹配,似乎只有T类型总是赢,所以

CSVFormat.rowToCSV((Seq("A")))

总是导致

""[(List(A))]""

任何想法如何使Scala泛型类型匹配,Seq[T]具有更高的优先级,以便它首先匹配?或者我应该在运行时确定类型而不是编译类型?如果是这样,我该怎么做?

1 个答案:

答案 0 :(得分:1)

valueToCSV方法的风格在编译时被解析,当时不知道您传入的类型是否是序列。

您需要进行动态类型检查。这样的事情怎么样:

 def rowToCSV[T <: Product](tuple: T) = tuple
  .productIterator
  .map { 
      case s: Seq[_] => s.mkString("{", ",", "}")
      case x => x.toString
   }.mkString("\"", "\",\"", "\"")

顺便说一下,调用函数时不需要括号,函数的唯一参数是元组:rowToCSV("foo")rowToCSV(("foo"))相同,rowToCSV(1, "foo", Seq("bar", "baz"))与{rowToCSV((1, "foo", Seq("bar", "baz")))相同1}}。