我正在尝试编写一个函数,它返回一个没有最后一个参数的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
上存在类型不匹配(我认为ClassTag
的C
)。有没有办法让它有两种方式,有一个ClassTag
和fun
?
你可以把它写成
foldArgs[Config](args).apply(fun)
或者(更糟)
foldArgs[Config](args)(implicitly)(fun)
(其中implicitly
可以指定类型:implicitly[ClassTag[Config]]
,或者可以用classTag
代替)。