简体   繁体   English

Scala通用类型方法匹配

[英]Scala generic type method matching

I am building a Scala generic type method that takes tuple with different size and output a line of CSV string. 我正在构建一个Scala通用类型方法,该方法采用具有不同大小的元组并输出一行CSV字符串。 The code I wrote is like this 我写的代码是这样的

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))}"
}

What I am trying to get is something like 我想要得到的是类似

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

then the output should be 那么输出应该是

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

The major issue here is for Seq[T] type matching and just T type matching for valueToCSV method, it seems just T type always win, so 这里的主要问题是Seq[T]类型匹配和valueToCSV方法的T类型匹配,似乎T类型总是赢,所以

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

always results in 总是导致

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

Any idea how to make Scala generic type matching, the Seq[T] has higher priority so that it got match first? 知道如何使Scala通用类型匹配, Seq[T]具有更高的优先级,以便首先获得匹配吗? Or should I determine type in runtime instead of compiling type instead? 还是应该在运行时确定类型而不是编译类型? If so, how should I do it? 如果是这样,我该怎么办?

The flavor of valueToCSV method is resolved at compile time, when it is not known whether the type you pass in is going to be a sequence or not. 当不知道您传入的类型是否为序列时,将在编译时解析valueToCSV方法的风格。

You need a dynamic type check instead. 您需要动态类型检查。 How about something like this: 这样的事情怎么样:

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

BTW, you don't need the parenthesis when calling a function, whose only argument is a tuple: rowToCSV("foo") is the same as rowToCSV(("foo")) and rowToCSV(1, "foo", Seq("bar", "baz")) is the same as rowToCSV((1, "foo", Seq("bar", "baz"))) . 顺便说一句,调用一个函数(其唯一的参数是元组)时不需要括号: rowToCSV("foo")rowToCSV(("foo"))rowToCSV(1, "foo", Seq("bar", "baz"))rowToCSV((1, "foo", Seq("bar", "baz")))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM