【问题标题】:Difference in Scala class, trait and object memory allocationScala 类、特征和对象内存分配的差异
【发布时间】:2013-12-06 16:20:13
【问题描述】:

在 Scala 中,有很多方法可以创建对象:

例如,通过new关键字创建类

class Car {   
  def startEngine() = println("run....") 
}
val car = new Car 
car.startEngine()  // run....

汽车对象应该像 Java 中的“新”对象一样位于堆中,并在被取消引用时等待被垃圾回收。

那么,如何通过 trait 来创建呢?

trait Car {
  def startEngine() = println("run...")
}
val car = new Car {}
car.startEngine() //run....

这是使用类 myCar 扩展 Car 创建对象的有效语法。 相反,它只是从 Trait 创建对象。

它是否对象堆中的席位? (我猜不是) 那么,它是否存在于堆栈中,并且一旦出局就会被取消引用为局部变量?

最后,通过 Object 怎么样?

object Car {
  def startEngine() = println("run...")
}
Car.startEngine()  //run....

这与通过 Trait 的情况相同吗?我相信对象更有可能存在于堆栈中。

有人可以解释一下这 3 种语法在内存分配方面的区别吗?

【问题讨论】:

    标签: scala


    【解决方案1】:

    它们都生活在堆中。 (另外,你的第二个例子并没有像写的那样工作。)

    区别在于代码重用。

    对于一个类,该类的每个新对象都运行相同的代码:

    class Car { }
    val c1 = new Car
    val c2 = new Car  // Same code as c1
    c1.getClass == c2.getClass  // true
    c1 eq c2                    // false--different objects on the heap
    

    有了一个特性,每次你用它创建一个类时,它都会复制代码(至少是一个转发器)。因此它的效率较低但更灵活(因为您可以在需要时将其混合到其他类中)。而且你可以通过添加{}为每个对象创建一个新的匿名类,所以很容易白做很多工作:

    trait Car { }
    val t1 = new Car {}   // Anon class #1
    val t2 = new Car {}   // Anon class #2--duplicate of #1
    t1.getClass == t2.getClass  // false
    

    对于一个对象,您明确表示将只有一个。你不能(没有低级诡计)得到另一个。

    object Car { }
    val o1 = Car
    val o2 = Car
    o1 eq o2     // true -- there is only one Car
    

    【讨论】:

      【解决方案2】:

      使用类(案例 1)或实现特征的匿名类(案例 2)在内存方面应该是相同的。请注意,您永远不能直接实例化特征。例如,new Car 将不起作用,但只有 new Car {} 会实例化一个扩展该特征的匿名类。

      使用单例对象显然只使用该“类”的一个实例。我认为顶级对象永远不会被垃圾回收,因此您不应该在单例对象中存储大量数据。

      【讨论】:

        猜你喜欢
        • 2017-10-25
        • 2015-05-26
        • 2020-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-14
        • 1970-01-01
        • 2016-03-08
        相关资源
        最近更新 更多