【问题标题】:Meaning of final for Scala constructor arguments and class/trait/object membersScala 构造函数参数和类/特征/对象成员的 final 的含义
【发布时间】:2015-09-09 16:45:51
【问题描述】:

final 对 Scala 构造函数参数意味着什么?我有这个例子:

class IntFinalTest(
    val intVal: Int,
    final val finalIntVal: Int,
    var intVar: Int,
    final var finalIntVar: Int) {
  //  intVal = 3 // error: reassignment to val
  //  finalIntVal = 3 // error: reassignment to val
  intVar = 3
  finalIntVar = 3
}

class ArrayFinalTest(
    val arrayVal: Array[Int],
    final val finalArrayVal: Array[Int],
    var arrayVar: Array[Int],
    final var finalArrayVar: Array[Int]) {
  arrayVal(0) = 3
  finalArrayVal(0) = 3
  arrayVar(0) = 3
  finalArrayVar(0) = 3
}

从编译器输出判断(只有两个标记的行会导致错误),final 和非final vals 和vars 之间没有区别 - 这是正确的吗?我通过运行此示例验证了除intValfinalIntVal 之外的所有变量都被修改了。

相关问题 RQ1final 在属于层次结构的类的构造函数中是否有任何意义?

相关问题 RQ2:如果 Array[Int] 是构造函数参数列表的一部分,我如何创建不可变的类成员?

上下文:我使用 Scala 2.10.5,并且只有几个月的使用经验。

【问题讨论】:

  • 我猜,final 表示它不能被覆盖。 (你知道,val arrayVal 创建了一个可以被覆盖的方法。)
  • Array[Int] - 总是可变的。试试Seq[Int]
  • @ArseniyZhizhelev 这应该是一个答案。
  • 我扩展了标题以反映相同的规则适用于类/特征/对象成员,正如 Jörg W Mittag 所指出的那样

标签: scala constructor final


【解决方案1】:

val 无法更改。但是val 可以 被覆盖,所以即使你在某处看到val,你也不能确定它的价值。 (在一般情况下,很难判断成员是否被覆盖。这称为类层次分析,相当于解决停止问题。)

一个final val,但是不能更改也不能被覆盖,所以你知道它的值永远不会与初始化它的值不同。带有varval 注释的构造函数参数成为类的成员,因此构造函数参数的final val 与“普通”类/特征/对象成员的含义大致相同.

请注意,对于(非构造函数)成员完全声明如下:

final val foo = e

即带有 explicit final 修饰符(即使 val 是隐式最终的,例如因为它在 final 类或 object 内),没有 em> 一个类型注解,如果econstant expression,则声明变为constant value declaration,Scala 语言规范保证编译器会对其进行优化。

【讨论】:

  • 你最后的笔记应该是我的下一个问题 :) 感谢您的精彩回答!
猜你喜欢
  • 1970-01-01
  • 2011-04-15
  • 2011-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多