Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 提取部分应用函数中的隐式转换异常_Scala_Implicit Conversion_Implicit - Fatal编程技术网

Scala 提取部分应用函数中的隐式转换异常

Scala 提取部分应用函数中的隐式转换异常,scala,implicit-conversion,implicit,Scala,Implicit Conversion,Implicit,我有一个使用宏构造的case类copy方法的映射,使用隐式转换将输入转换为正确类型的copy方法,称为JsValue是Play Framework json值 case class Clazz(int: Int, string: String) implicit def jsonToInt(json: JsValue): Int = json.as[Int] implicit def jsonToStr(json: JsValue): String = json.as[String] val

我有一个使用宏构造的case类copy方法的映射,使用隐式转换将输入转换为正确类型的copy方法,称为JsValue是Play Framework json值

case class Clazz(int: Int, string: String)

implicit def jsonToInt(json: JsValue): Int = json.as[Int]
implicit def jsonToStr(json: JsValue): String = json.as[String]

val copyMap: Map[String, (Clazz, JsValue) => Clazz] = 
  Map("int" -> (c: Clazz, json: JsValue) => c.copy(int = json),
      "string" -> (c: Clazz, json: JsValue) => c.copy(string = json))
我想对从copyMap检索到的函数部分应用一个输入,例如

在这种情况下,当尝试在完全应用函数时将JsStringnon_int_输入转换为int时,函数将引发异常,但我希望在部分应用JsValue输入时出现此错误-完全应用函数涉及从数据库检索Clazz实例,所以如果字符串输入无效,我宁愿抢占它


是否有一种方法可以触发/提取部分应用函数中的任何隐式转换错误?

我想我可能已经找到了解决方案

case class Clazz(int: Int, string: String)

implicit def jsonToInt(json: JsValue) = json.as[Int]
implicit def jsonToStr(json: JsValue) = json.as[String]

val copyMap[String, (JsValue) => Try[(Clazz) => Clazz]] = 
  Map(
    "int" -> {
      (json: JsValue) => Try[(Clazz) => Clazz] = 
        Try {
          val i: Int = json
          (c: Clazz) => c.copy(int = i)
        }
      },
    "string" -> {
      (json: JsValue) => Try[(Clazz) => Clazz] = 
        Try {
          val s: String = json
          (c: Clazz) => c.copy(string = s)
        }
      }
    )
当我打电话给纽芬时,它将是一个失败者

val fun: (JsValue) => Try[(Clazz) => Clazz] = copyMap.get("int").get
val newFun: Try[(Clazz) => Clazz] = fun(JsString("non_int_input"))
这方面的宏代码是,我在c.universe中遇到了与Try的导入冲突。\因此使用了scala.util.Try


@EugeneBurmako我在上面添加了宏代码,以演示触发解析错误的含义——调用case类Clazzi:Int;copyMap[Clazz].geti.getJsStringcan not parse as Int将返回失败,因为无法使用隐式转换将JsValue解析为Int
val fun: (JsValue) => Try[(Clazz) => Clazz] = copyMap.get("int").get
val newFun: Try[(Clazz) => Clazz] = fun(JsString("non_int_input"))
import play.api.libs.json._
import scala.language.experimental.macros

object Macros {
  implicit def jsonToInt(json: JsValue): Int = json.as[Int]
  implicit def jsonToIntOpt(json: JsValue): Option[Int] = json.asOpt[Int]
  implicit def jsonToStr(json: JsValue): String = json.as[String]
  implicit def jsonToStrOpt(json: JsValue): Option[String] = json.asOpt[String]

  def copyMap[T]: Map[String, (JsValue) => scala.util.Try[(T) => T]] = macro copyMapImpl[T]

  def copyMapImpl[T: c.WeakTypeTag](c: scala.reflect.macros.Context): 
      c.Expr[Map[String, (JsValue) => scala.util.Try[(T) => T]]] = {

    import c.universe._
    val tpe = weakTypeOf[T]

    val fields = tpe.declarations.collectFirst {
      case m: MethodSymbol if m.isPrimaryConstructor => m
    }.get.paramss.head

    val methods = fields.map {
      field => {
        val name = field.name
        val decoded = name.decoded
        val fieldType = field.typeSignature.typeSymbol
        val fieldTypeName = fieldType.name.decoded
        q"""{$decoded -> {
          (json: JsValue) => scala.util.Try {
           val x: $fieldType = json
           (t: $tpe) => t.copy($name = x)
          }.recoverWith {
            case e: Exception => scala.util.Failure(
              new IllegalArgumentException("Failed to parse " + Json.stringify(json) + " as " + $decoded + ": " + $fieldTypeName)
            )
          }
        }}"""
      }
    }

    c.Expr[Map[String, (JsValue) => scala.util.Try[(T) => T]]] {
      q"Map(..$methods)"
    }
  }
}