加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala无实例不==无

发布时间:2020-12-16 21:32:58 所属栏目:安全 来源:网络整理
导读:我在 Scala代码中有一个间歇性问题,我正在使用带有String键的不可变地图的值.这是基本代码,包括我添加的调试日志: val compStruct = subsq.comps get (ident) compStruct match { ... case None = logger.info(s"Found None,of type ${compStruct.getClass.
我在 Scala代码中有一个间歇性问题,我正在使用带有String键的不可变地图的值.这是基本代码,包括我添加的调试日志:

val compStruct = subsq.comps get (ident)
  compStruct match {
    ...
    case None =>
      logger.info(s"Found None,of type ${compStruct.getClass.getName},at position $position (ident $ident)")
      ...
    case x =>
      logger.info(s"Illegal structure of type ${x.getClass.getName} at position $position (ident $ident) - x == None is ${x == None},x.getClass == None.getClass is ${x.getClass == None.getClass},x.getClass.getName == None.getClass.getName (${None.getClass.getName}) is ${x.getClass.getName == None.getClass.getName}")
      ...
  }

问题是,当值实际上是None时,有时会采用x,如(消毒)调试输出所示:

INFO  ...: Found None,of type scala.None$,at position 3000 (ident XX)
  INFO  ...: Illegal structure of type scala.None$at position 3200 (ident XX) - x == None is false,x.getClass == None.getClass is true,x.getClass.getName == None.getClass.getName (scala.None$) is true

(第一行是我预期会发生的,确实发生正常;其余的是错误的情况)

所以如果我的记录是相信的(我没有弄乱我的表情)我有一个案例,地图返回x,其中x是类scala.None $(同一个类scala)的实例.没有$,如编译代码所见),但不匹配的情况下,None和x == None是false.

类加载问题是明显的原因,但x.class == None.class似乎排除了这一点.

添加:正如我在评论中建议的,我可以重现无与以下代码不匹配的实例:

object Test {
  def main(args: Array[String]): Unit = {
    val none1 = None
    val clas = this.getClass.getClassLoader.loadClass("scala.None$")
    val constr = clas.getDeclaredConstructors()(0)
    constr.setAccessible(true)
    val none2 = constr.newInstance()
    println(s"none1 == none2 is ${none1 == none2}")
    println(s"none1 == None is ${none1 == None}")
    println(s"none2 == None is ${none2 == None}")
  }
}

这使:

none1 == none2 is false
none1 == None is false
none2 == None is true

不过,我认为这与应用程序中发生的事情并无任何关系.

添加:我修改了实际的无$类文件,当构造函数执行时都打印一条消息,并在调用构造函数时$$.MODULE $value为非空,并将商店移动到静态MODULE $值到静态构造函数块(原始代码在构造函数中有这个存储,我认为在技术上是违反JVM规则,因为在构造函数返回之后,对象不被视为初始化).

这样做会阻止对构造函数(上面的代码示例)的反射调用,它复制了问题的症状,但并没有改变实际应用程序中的任何内容.即使该类保持不变(相同的System.identityHashCode),无$.MODULE $的值从代码的一个执行变为下一个,但构造函数只被调用一次.

解决方法

关于你的考试:
Scala中没有一个对象.当你定义
val none1 = None,你分配给none1这个对象,这应该是一个单例.

通过使用反射,您将绕过私有构造函数并创建一个新的None类实例.如果两个指针指向同一个对象,则==操作符将返回true.
您可以使用System.identityHashCode(none1)验证这些对象的内存地址并进行比较.

此外,如果您尝试在对象Test中运行与none1的匹配,则会遇到匹配错误,因为None的第二个实例与None或x不匹配.

我能够重现您的错误.通过运行这段代码:

val a = Map("a" -> "b","b" -> None)
a.get("b") match { 
   case None => print("None")
   case x => print("X") 
}  // Prints X
a.get("c") match { 
    case None => print("None")
    case x => print("X") 
} // Prints None

我知道这不能解释为什么它打印X,但至少你知道什么时候…

因为您的HashMap没有值,它是一个HashMap [String,java.io.Serializable],而不是HashMap [String,String].
而get的调用将返回java.io.Serializable而不是String.

为了解决你的问题,当它是None时,它可以匹配,你可以做:

case x if(x.isInstanceOf[None$]) =>

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读