我正在构建一个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]
具有更高的优先级,以便它首先匹配?或者我应该在运行时确定类型而不是编译类型?如果是这样,我该怎么做?
答案 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}}。