【发布时间】:2019-04-12 21:42:13
【问题描述】:
我正在尝试编写一个返回 foldLeft 且不带最后一个参数的函数,并且我还需要将其设为参数。我需要一个 ClassTag 作为这个参数,但我似乎无法同时拥有一个 implicit ClassTag 并为范围留出空间来完成该功能:
def fields[T](implicit ctag: ClassTag[T]) : Array[String] =
ctag.runtimeClass.getDeclaredFields.map(_.getName)
def foldArgs[C](args: Array[String])(implicit ctag: ClassTag[C])
: ((C, (String, String)) => C) => C = {
val tt = weakTypeTag[C].tpe
val clsMirror = universe
.runtimeMirror(getClass.getClassLoader)
.reflectClass(tt.typeSymbol.asClass)
val ctorSym = tt.decl(universe.termNames.CONSTRUCTOR).asMethod
val instance = clsMirror.reflectConstructor(ctorSym)().asInstanceOf[C]
fields[C].zip(args).foldLeft(instance)
}
case class Config(a: Int, b: Double, c: String)
def fun: (Config, (String, String)) => Config = ???
def main(args: Array[String]): Unit = {
Try { foldArgs[Config](args)(fun) } match {
case Success(a) => println(a)
case Failure(e) => println(s"${e.getMessage}")
}
}
foldArgs 中的最后一行需要将ClassTag[C] 传递给fields,但是如何创建ClassTag[C]?看来我必须反过来将它作为implicit 传递给foldArgs 本身,这现在会中断调用foldArgs[Config](args)(fun):编译器告诉我fun 上存在类型不匹配(它期待@987654333 @ 为C 我认为)。有什么办法可以同时拥有ClassTag 和fun?
【问题讨论】: