【问题标题】:What is the difference between "Array.fill(2)(new A)" and "val a=new A; Array.fill(2)(a)"?“Array.fill(2)(new A)”和“val a=new A; Array.fill(2)(a)”有什么区别?
【发布时间】:2012-11-23 21:34:11
【问题描述】:

最小的工作示例(Scala 2.9.2):

object Main extends App {
  class A {
    var a=0
  }
  val b = Array.fill(2)(new A)
  b(1).a = 9
  println(b(0).a) //prints 0
  println(b(1).a) //prints 9

  val a = new A
  val c = Array.fill(2)(a)
  c(1).a = 9
  println(c(0).a) //prints 9
  println(c(1).a) //prints 9
}

一个相关的问题是“导入的 Java 类也一样吗?” 如果我需要使用作为参数传递的实例的副本填充函数内部的数组,我该如何解决? [关于相同的副本,我值得检查一下简单的cloning library

只需根据答案将解决方法添加到函数调用中:

  class A {
    var a=0
  }

  def f(a: => A) {             // "=>" added
    val b = Array.fill(2)(a)
    b(1).a=9
    println(b(0).a) //prints 0
    println(b(1).a) //prints 9
  }

  f(new A)

另一种方法是声明一个函数,而不是一个值def a = new A

object Main extends App {
  class A {
    var a=0
  }
  val b = Array.fill(2)(new A)
  b(1).a = 9
  println(b(0).a) //prints 0
  println(b(1).a) //prints 9

  def a = new A
  val c = Array.fill(2)(a)
  c(1).a = 9
  println(c(0).a) //prints 0
  println(c(1).a) //prints 9
}

【问题讨论】:

    标签: class scala new-operator cloning scala-2.9


    【解决方案1】:

    fill 方法的第二个参数定义为“按名称调用”。这意味着对数组中的每个单元格重新评估传入的块。在定义中看到elem的类型是=> T,而不是简单的T

    def fill[T: ClassManifest](n: Int)(elem: => T): Array[T]
    

    因此,在您的第一个版本中,块 new A 会为每个单元格重新评估,这意味着每个单元格都会获得一个新的 A 对象。在第二个版本中,new A 仅被调用一次,并且该对象被放置到每个单元格中。

    如果你在 REPL 上运行,你实际上可以看到这一点:

    scala> val b = Array.fill(2)(new A)
    b: Array[A] = Array(A@2049bed2, A@498edd8d)    // two different objects
    
    scala> val c = Array.fill(2)(a)
    c: Array[A] = Array(A@31e0c0b6, A@31e0c0b6)    // the same object repeated
    

    【讨论】:

    • 旁注:toString() 显示的是十六进制代码,而不是内存地址。
    【解决方案2】:

    看看fill的签名

    def fill[T: ClassManifest](n: Int)(elem: => T)
    

    所以它得到一个按名称调用的参数,这意味着每次处理数组中的单元格时都会执行new A

    【讨论】:

      【解决方案3】:

      一个用 A 的单个实例填充数组,另一个用 A 的新实例填充数组。

      【讨论】:

        猜你喜欢
        • 2021-09-17
        • 2016-02-17
        • 1970-01-01
        • 2014-04-12
        • 1970-01-01
        • 2013-05-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多