Scala泛型函数,用于将字符串转换为泛型类型

Yev*_*ych 2 generics scala

我有一个函数应该找到命令行参数与它的值并返回转换为类型P:

def parameter[P](name: String)(implicit tag: ClassTag[P]): P = {

    val paramName = s"--$name"

    args.sliding(2, 2).toList.collectFirst {
      case Array(`paramName`, param: String) => {
        // if P is Int => param.toInt
        // if P is Double => param.toDouble
      }
    }.get
  }
Run Code Online (Sandbox Code Playgroud)

我怎么做?我发现这ClassTag是一种方法,但在这种情况下无法弄清楚如何使用它.

Tra*_*own 5

您可以将类标记与要匹配的类型的标记进行比较:

import scala.reflect.{ClassTag, classTag}

def parameter[P](args: Array[String], name: String)(implicit tag: ClassTag[P]): P = {
  val paramName = s"--$name"

  args.sliding(2, 2).toList.collectFirst {
    case Array(`paramName`, param: String) => (
      if (tag == classTag[Double]) {
        param.toDouble
      } else if (tag == classTag[Int]) {
        param.toInt
      } // and so on...
    ).asInstanceOf[P]
  }.get
}
Run Code Online (Sandbox Code Playgroud)

当然,您也可以使用模式匹配或其他任何方式.它按预期工作:

scala> parameter[Int](Array("--foo", "123"), "foo")
res0: Int = 123

scala> parameter[Double](Array("--foo", "123"), "foo")
res1: Double = 123.0
Run Code Online (Sandbox Code Playgroud)

这种方法有很多缺点,但是你必须知道你想要在定义中解析的所有类型parameter等等 - 而且你可能最好使用专门为解析你的那种类型而设计的类型类'干嘛.