下面的Scala类是可变的还是不可变的?
我认为它是不可变的,因为我无法编辑变量或在创建变量后访问它们但是让我怀疑自己是因为它使用其函数返回变量的当前实例。它也没有最终在它面前,这进一步让我怀疑自己。
class person(name:String, dob:String){
def getName = name
def getDob = dob
def display() = {
println("Name "+name+" dob: "+dob)
}
}
谢谢,
答案 0 :(得分:1)
您对术语不可变有误解:
我认为它不可变,因为我无法编辑变量或访问 它们一旦创建就
私有事物(方法,变量,......)的定义。不变性指的是你不能改变状态,也就是说,除非你创建一个新的实例,否则你不能改变某些东西的价值。
让我们看一个例子:
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
)的实例中,您正在更改类属性的状态,在这种情况下{{1}每次调用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
的每次调用都将计算为2。也就是说,因为我们正在处理不可变值(changeState
)。每次val myMutableValue = 1
的调用都将执行评估并返回该值的副本。您未以任何方式修改changeState
的价值。
另外,请看一下你的代码,你有一些错误:
myMutableValue
而不是Person
)。person
(def
和def getName
)重新分配您的班级值。您可以按原样使用类值。最后:
它也没有最终在它面前,这进一步使我 怀疑自己。
再一次,你在谈论不同的事情。与Java一样,def getDob
是一个修饰符,可以防止您的类成为final
。 它不以任何方式与不变性相关在adition中,如果你想防止你的子类中的可变性,你必须让他们的所有成员extended
(see this) 。
由于您的示例是使用Scala编写的,因此您可以使用该语言本身提供的所有工具(例如final
,val
,sealed
)
请注意,我已使用final
来解释trait
的可能用途。
编辑:about final
modifier and immutability
感谢@Silvio Mayolo和@puhlen对def