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

避免Scala内存泄漏 – Scala构造函数

发布时间:2020-12-16 19:01:40 所属栏目:安全 来源:网络整理
导读:我正在通过“ Scala”中的编程工作,并在第6章中对Rational Rational类的实现中遇到了一个问题. 这是我的Rational类的初始版本(基于本书) class Rational(numerator: Int,denominator: Int) { require(denominator != 0) private val g = gcd(numerator.abs,d
我正在通过“ Scala”中的编程工作,并在第6章中对Rational Rational类的实现中遇到了一个问题.

这是我的Rational类的初始版本(基于本书)

class Rational(numerator: Int,denominator: Int) {
  require(denominator != 0)

  private val g = gcd(numerator.abs,denominator.abs)

  val numer = numerator / g
  val denom = denominator / g

  override def toString  = numer + "/" + denom

  private def gcd(a: Int,b: Int): Int =
    if(b == 0) a else gcd(b,a % b)

  // other methods go here,neither access g
}

这里的问题是,即使没有再次访问,该字段仍保留在该类的一生中.运行以下模拟程序可以看到这个问题:

object Test extends Application {

  val a = new Rational(1,2)
  val fields = a.getClass.getDeclaredFields

  for(field <- fields) {
    println("Field name: " + field.getName)
    field.setAccessible(true)
    println(field.get(a) + "n")
  }  

}

其产出将是:

Field: denom
2

Field: numer
1

Field: g
1

我在Scala Wiki发现的一个解决方案涉及到:

class Rational(numerator: Int,denominator: Int) {
  require(denominator != 0)

  val (numer,denom) = { 
    val g = gcd(numerator.abs,denominator.abs)
    (numerator / g,denominator / g)
  }

  override def toString  = numer + "/" + denom

  private def gcd(a: Int,a % b)

  // other methods go here
}

这里,字段g只是其块的本地,但是运行小测试应用程序时,我发现另外一个字段x $1,它保留由(号,denom)组成的元组的副本!

Field: denom
2

Field: numer
1

Field: x$1
(1,2)

有没有办法用上述算法在Scala中构造一个理性,而不会引起任何内存泄漏?

谢谢,

Flaviu Cipcigan

解决方法

你可以这样做:

val numer = numerator / gcd(numerator.abs,denominator.abs)
val denom = denominator / gcd(numerator.abs,denominator.abs)

当然,你必须做两次计算.但是,优化通常是内存/空间与执行时间之间的折衷.

也许还有其他的方法,但是程序可能会变得过于复杂,如果有一个地方优化很少成熟,那就是大脑力量优化:).例如,你可能会这样做:

val numer = numerator / gcd(numerator.abs,denominator.abs)
val denom = denominator / (numerator / numer)

但这并不一定使代码更容易理解.

(注意:我没有真的尝试这样做,所以使用自己的风险.)

(编辑:李大同)

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

    推荐文章
      热点阅读