【问题标题】:Is this class Immutable or mutable这个类是不可变的还是可变的
【发布时间】:2017-07-30 23:38:37
【问题描述】:

下面的 Scala 类是可变的还是不可变的?

我相信它是不可变的,因为一旦创建变量我就无法编辑或访问它们,但让我怀疑的是它使用其函数返回变量的当前实例这一事实。它前面也没有final,这进一步让我怀疑自己。

class person(name:String, dob:String){
  def getName = name
  def getDob = dob
  def display() = {
    println("Name "+name+" dob: "+dob)
  }
}

谢谢,

【问题讨论】:

    标签: scala


    【解决方案1】:

    你对不可变这个词有误解:

    我相信它是不可变的,因为我无法编辑变量或访问 他们一旦创建

    这就是 private 事物(方法、变量、...)的定义。不变性是指你不能改变状态,也就是说,除非你创建一个新的实例,否则你不能改变它的值

    我们来看一个例子:

    trait Foo{
      def myMutableValue: Int
    }
    
    class Clazz extends Foo{
    
      var myMutableValue = 1
    
      def changeState(): Int = {
        myMutableValue += 1
        myMutableValue
      }
    }
    
    val bar = new Clazz
    
    bar.changeState() // myMutableValue = 2
    bar.changeState() // myMutableValue = 3
    bar.changeState() // myMutableValue = 4
    
    bar.myMutableValue // myMutableValue = 4
    

    在这个例子中,在Clazz (bar) 的 instance 中,您正在更改类属性的状态,在这种情况下,myMutableValue 每次我都会更改其值调用changeState。 请注意,该类默认是公开的,changeState 也是公开的,但这并不意味着它是不可变的。

    现在,让我们看看不可变的方法:

    trait Foo{
      def myMutableValue: Int
    }
    
    class Clazz extends Foo{
    
      val myMutableValue = 1
    
      def changeState(): Int = myMutableValue + 1
    }
    
    val instance = new Clazz
    
    instance.changeState() // myMutableValue = 2
    instance.changeState() // myMutableValue = 2
    instance.changeState() // myMutableValue = 2
    
    instance.myMutableValue // 1
    

    使用这种方法,无论我调用多少次函数,每次调用 changeState 都会计算为 2。也就是说,因为我们正在处理一个不可变的值 (val myMutableValue = 1)。 changeState 的每次调用都将执行评估并返回该值的副本。您不会以任何方式修改 myMutableValue 的值。

    请查看thisthis

    另外,请看一下你的代码,你有一些错误:

    • 按照惯例,类名应大写(Person 而不是person)。
    • 不需要使用defdef getNamedef getDob)重新分配您的班级值。您可以按原样使用类值。

    最后:

    它前面也没有final,这进一步让我 怀疑自己。

    再一次,你在谈论不同的事情。 final 与 Java 中一样,是一个修饰符,可防止您的类成为 extended它与不变性没有任何关系 此外,如果你想防止你的子类中的可变性,你必须让它们的所有成员final (see this)。 由于您的示例是用 Scala 编码的,因此您可以使用该语言本身提供的所有工具(例如 valsealedfinal

    请注意,我使用了trait 来解释def 的可能用法。

    编辑:about final modifier and immutability

    感谢@Silvio Mayolo 和@puhlen 对final987654350@的cmets 和澄清

    【讨论】:

    • final 在 Java 中也可以用在变量之前,表示接近 Scala 的 val 的含义,因此它确实与不变性有关。它只是不在 Scala 中。
    • final 确实与不变性有关,如果不是直接的话。非最终类的问题是可以创建一个子类并覆盖成员以使它们可变。由于多态,这可以让你认为你有一个不可变的类,但实际上是在使用一个可变的子类。
    猜你喜欢
    • 2010-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    • 2014-08-05
    相关资源
    最近更新 更多