在通用函数中转换数据类型时无效。toint 被调用,但 v 的类型仍然是 double

乐手

我想实现一种将 JSON 数据转换为 Scala 内置对象的方法。该代码类似于以下内容:

  implicit class JsonNodeToScala(jsonNode: JsonNode) {

    import scala.jdk.CollectionConverters._
    import scala.reflect.{ClassTag,classTag}

    def toSeq[T: ClassTag]: Seq[Option[T]] = jsonNode.elements.asScala.map(_.toScala[T]).toSeq

    def toMap[T: ClassTag]: Map[String, Option[T]] = jsonNode.fields.asScala.map(field => (field.getKey, field.getValue.toScala[T])).toMap

    def toScala[T: ClassTag]: Option[T] = (this.jsonNode match {
      case v if v.isBoolean => v.asBoolean
      case v if v.isNumber =>
        (v.asDouble, classTag.runtimeClass) match {
          case (v, c) if c == classOf[Int] => 
            print("toInt")
            v.toInt
          case (v, c) if c == classOf[Long] => 
            print("toLong")
            v.toLong
          case (v, _) => v
        }
      case v if v.isTextual => v.asText
      case jsonNode => jsonNode
    }) match {
      case v: T => Some(v)
      case v => 
        println(v, classTag.runtimeClass, v.getClass)
        None
    }
  }

当我使用它时它工作如下

new ObjectMapper().readTree("""[1,2,null,4]""").toSeq[Double]
>>> res136: Seq[Option[Double]] = List(
  Some(value = 1.0),
  Some(value = 2.0),
  None,
  Some(value = 4.0)
)

但是当我传入泛型参数int时,却得不到我想要的结果。

new ObjectMapper().readTree("""[1,2,null,4]""").toSeq[Int]
>>>
    toInt(1.0,int,class java.lang.Double)
    toInt(2.0,int,class java.lang.Double)
    (null,int,class com.fasterxml.jackson.databind.node.NullNode)
    toInt(4.0,int,class java.lang.Double)
 
res138: Seq[Option[Int]] = List(None, None, None, None)

结果调用了toint,但是v的类型还是double。是不是 Scala 在 match case 中的处理造成的?

如果我想满足我的需求,我应该如何修改我的代码?

"[1, 2, 3]" call toSeq[Int]  => Seq(1, 2, 3)
"[1, 2, 3]" call toSeq[Double]  => Seq(1.0, 2.0, 3.0)

"[1.0, 2.0, 3.0]" call toSeq[Int]  => Seq(1, 2, 3)
"[1.0, 2.0, 3.0]" call toSeq[Double]  => Seq(1.0, 2.0, 3.0)
詹卢卡·阿古齐

这里的主要问题是:

case v if v.isNumber =>
  (v.asDouble, classTag.runtimeClass) match {
    case (v, c) if c == classOf[Int] => 
      print("toInt")
      v.toInt
    case (v, c) if c == classOf[Long] => 
      print("toLong")
      v.toLong
    case (v, _) => v
  }

Scala 编译器必须找到Int,Long之间的公共最低祖先Double在 Scala 2.12 中,它恰好是Double,所以它再次转换IntDouble(通过隐式转换)。一种欺骗编译器的方法应该是向上转换一些返回类型,这样它就不能在数字类型之间执行隐式类型转换。例如:

case v if v.isNumber =>
  (v.asDouble, classTag.runtimeClass) match {
    case (v, c) if c == classOf[Int] => 
      print("toInt")
      v.toInt
    case (v, c) if c == classOf[Long] => 
      print("toLong")
      v.toLong
    case (v, _) => (v : Any) // common lowest type now is Any, no conversions will be performed
  }

我希望我能帮助你:)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

追加克隆的模板仍然是fragment类型

(JNI) 从 cpp lib 调用函数时的数据类型转换

Java“无法取消引用double”错误-double数据类型上的调用方法

在Matlab中转换数据类型的有效方法(double与im2double)

错误:被调用的对象类型“ double”不是函数或函数指针

SML从数据类型调用函数

参数数据类型 nvarchar 对于 SSRS 中转换函数的参数 3 无效

MongoDB 中的自定义 _id 字段是否仍然是 ObjectId 类型

HandlebarsJS:匹配预编译/运行时版本,仍然是“未捕获的类型错误”

Java错误:无法在原始类型double上调用size()

如果我使用`sudo`运行命令,它仍然是“由普通用户调用的”吗?

当返回空数据时,从“ DBNull”类型到“ Double”类型的转换无效

数据类型为double而不转换为因数

将可为空的double转换为double类型的数据类型

执行过程中转换数据类型时出错

调用auth.login()后,Django用户仍然是AnonymousUser

不等待异步调用仍然是异步的,对吗?

调用OpenCV函数时,Numpy和OpenCV2数据类型冲突

调用函数检查不同数据类型时,对AngIf类的布尔属性进行角分配

具有两种状态变量类型(输入和输出)的状态单子仍然是单子吗?

从C调用包含STL数据类型的C ++函数

数据类型在函数调用中不匹配

如何用不同的数据类型调用相同的函数?

对if语句使用Double数据类型

比double更精确的数值数据类型?

Double数据类型变量的范围检查

从类型 string 到 double 的转换无效

无法为类型为((String?)'的参数列表调用类型为'Double'的初始化程序

无法使用类型为“([Int])”的参数列表调用类型“Double”的初始化程序