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

scala隐式导致StackOverflowError

发布时间:2020-12-16 18:52:36 所属栏目:安全 来源:网络整理
导读:这个隐式val如何导致StackOverFlowError? (削减我的原始代码,仍然导致错误) object Complicit { // a class with name,default,and conversion function as implicit val case class CC[A](name: String,defaultValue: A)(implicit val convert: String = A
这个隐式val如何导致StackOverFlowError?

(削减我的原始代码,仍然导致错误)

object Complicit {
  // a class with name,default,and conversion function as implicit val
  case class CC[A](name: String,defaultValue: A)(implicit val convert: String => A) {
    def getFrom(s: String): A= try { 
      convert(s) 
    } catch { 
      case t: Throwable => 
        println("ERROR: %s".format(t))  // just to see the StackOverflowException
        defaultValue
    }
  }  

  // this works fine
  object Works {
    val cc1= CC("first",0.1)(_.toDouble)
  } 

  // this causes java.lang.StackOverflowError due to the implicit
  object Fails {
    // !!! StackOverFlowError here
    implicit val stringToDouble: String => Double= { _.toDouble }

    val cc2= CC("second",0.2)
  }

  def main(args: Array[String]) {
    // this works
    println("%s %f".format(Works.cc1.name,Works.cc1.getFrom("2.3")))
    // this fails
    println("%s %f".format(Fails.cc2.name,Fails.cc2.getFrom("4.5")))
  }
}

我是否在做违法行为?

解决方法

我相信我可以回答这里发生的事情..它与其他隐式转换以及您刚创建的转换有关.如果你添加这个跟踪,你可以确认通常与哪些堆栈溢出有关 – 一个函数自己重复调用,直到java的堆栈空间崩溃:

implicit val stringsToDouble: String => Double= { x=>println("called inner "+x); x.toDouble }

….
叫内在4.5
叫内在4.5
叫内在4.5
叫内在4.5
调用内部4.5ERROR:java.lang.StackOverflowError

我认为发生的事情是这样的 – toDouble不是java字符串的自然功能,而是使用StringOps中的隐式转换(或StringLike,我不是很确定,但它是同一个问题).

因此,当您调用toDouble时 – 编译器开始寻找可能包含函数“toDouble”的隐式转换.理论上它可以是任何结果类.

但是 – 如果有几个隐式转换可以实现这一目标会发生什么?不幸的是,“Double”还包含功能toDouble,如下所示:

val x = 44.4
x.toDouble

你猜怎么着?这意味着你现在最接近范围的新隐式函数赢得了比赛,并且在圆圈中调用以完成“toDouble” – 有效地尝试将字符串转换为double,以便重复调用toDouble(在Double类上).我承认这很令人困惑,但证据确实合适.

这是修复..它符合解释并阻止递归调用.

implicit val stringsToDouble: String => Double= { java.lang.Double.parseDouble(_)  }

(编辑:李大同)

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

    推荐文章
      热点阅读