我正在尝试编写一个返回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)
:编译器告诉我{{1 }}(我认为fun
会使用ClassTag
)。有没有办法同时拥有C
和ClassTag
?
答案 0 :(得分:1)
您可以将其写为
resolve_redirects
或(更糟)
foldArgs[Config](args).apply(fun)
(其中foldArgs[Config](args)(implicitly)(fun)
可以指定类型:implicitly
,或者可以用implicitly[ClassTag[Config]]
代替)。