为什么允许Scala中的最终变量更改值。根据我的理解,一旦宣布最终,他们就不应该被允许改变。
class foo()
{
final var name = "abc"
name = "xyz" // why this is allowed
}
答案 0 :(得分:11)
final
关键字与Java中的含义不同。
在Java中,它既可以意味着无法扩展或覆盖类或方法,也可以表示引用是不可变的。
在Scala final
中只有第一个含义,而要有不可变引用,您应该使用val
关键字。
class Foo {
val name: String = "abc"
// name = "xyz" // would be a compilation error
final var surname: String = "def"
surname = "uvw" // ok
}
class Bar extends Foo {
override val name: String = "xyz"
override var surname: String = "rst" // compilation error
}
答案 1 :(得分:7)
final
:
final修饰符适用于类成员定义和类定义。 最终的类成员定义可能不会在子类中重写。一个 最终的课程可能不会被模板继承。决赛是多余的 对象定义。最终类或对象的成员是隐式的 也是最终的,所以最终修饰符通常是多余的, 太。但请注意,常量值定义确实需要 显式最终修饰符,即使它们是在最终类中定义的 宾语。 final可能不适用于不完整的成员,也可能不适用 合并在一个密封的修饰符列表中。
由于Scala中的val
定义已经意味着对它的引用是不可变的(与Java不同),因此在定义它时不必明确指定它。如果希望将值作为字节代码中的常量内联,则可以指定添加final
修饰符。
根据var
,final在这里仅表示“可能不会在子类中重写,但对变量的 immutability 一无所知:
scala> :pa
// Entering paste mode (ctrl-D to finish)
class Foo {
final var name = "abc"
}
class Bar extends Foo {
override var name = "yuval"
}
// Exiting paste mode, now interpreting.
<console>:16: error: overriding variable name in class Foo of type String;
variable name cannot override final member
override var name = "yuval"
答案 2 :(得分:2)
关于final
,无论是否扩展或覆盖类/变量,它都会出现。
class Fruit {
val color = "Green"
}
class AmericanFruit extends Fruit {
override val color = "Red"
}
此外,无法继承final
类,
将val
用于不可变数据。 (val
表示不可变值)
例如
scala> val immutableName = "you can not change me"
immutableName: String = you can not change me
scala> immutableName = "change me"
<console>:12: error: reassignment to val
immutableName = "change me"
^
对于mutable,您使用var
(var
作为变量)
scala> var mutableName = "you can change me"
mutableName: String = you can change me
scala> mutableName = "i am changed"
mutableName: String = i am changed