【问题标题】:Implicit classTag and currying隐式 classTag 和柯里化
【发布时间】: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 我认为)。有什么办法可以同时拥有ClassTagfun

【问题讨论】:

    标签: scala implicit


    【解决方案1】:

    你可以写成

    foldArgs[Config](args).apply(fun)
    

    或(更糟)

    foldArgs[Config](args)(implicitly)(fun)
    

    (其中implicitly可以指定类型:implicitly[ClassTag[Config]],也可以替换为classTag)。

    【讨论】:

    • 它在编译时工作,但我在运行时得到free type C is not a class
    • 啊,这是weakTypeTag[C].tpe的结果。它只返回未绑定到任何东西的类型参数,因此 asClass 失败。我想你根本不需要它,可以使用val instance = ctag.runtimeClass.newInstance().asInstanceOf[C]
    • 等等,不,您的构造函数需要参数,但您没有在clsMirror.reflectConstructor(ctorSym)() 中传递任何参数。所以你需要弄清楚你想如何处理它。无论如何,只有TypeTag 而不是WeakTypeTag 可以工作。您可以从ClassTag 创建它,反之亦然(例如stackoverflow.com/questions/22970209/get-typetaga-from-classa/…stackoverflow.com/questions/18729321/…),或者只是添加为另一个隐式参数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-16
    • 2013-11-07
    • 2011-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多