为什么不将val或var变量标记为私有?

blu*_*sky 1 encapsulation scala

来自java背景我总是将实例变量标记为私有.我正在学习scala,几乎所有我看过val/var实例的代码都有默认(公共)访问权限.为什么这是访问?它不会打破信息隐藏/封装原则吗?

Rex*_*err 7

它可以帮助你指定哪些代码,但请记住,一些示例代码是以简化的形式突出显示该示例应该向您显示的内容.由于默认访问是公开的,这意味着为了简单起见,您经常会将修改符保留.

也就是说,因为a val是不可变的,所以只要你认识到这现在是你班级API的一部分,那么公开它就没什么害处.那可以完全没问题:

class DataThingy(data: Array[Double) {
  val sum = data.sum
}
Run Code Online (Sandbox Code Playgroud)

或者它可以是您不应公开的实现细节:

class Statistics(data: Array[Double]) {
  val sum = data.sum
  val sumOfSquares = data.map(x => x*x).sum
  val expectationSquared = (sum * sum)/(data.length*data.length)
  val expectationOfSquare = sumOfSquares/data.length 
  val varianceOfSample = expectationOfSquare - expectationSquared
  val standardDeviation = math.sqrt(data.length*varianceOfSample/(data.length-1))
}
Run Code Online (Sandbox Code Playgroud)

在这里,我们用我们所有的中间步骤来计算标准偏差.鉴于这不是用浮点数计算标准偏差的数值最稳定的方法,这是特别愚蠢的.

不是仅仅将所有这些都设为私有,如果可能的话,使用本地块或private[this]def来执行中间计算是更好的风格:

val sum = data.sum
val standardDeviation = {
  val sumOfSquares = ...
  ...
  math.sqrt(...)
}
Run Code Online (Sandbox Code Playgroud)

要么

val sum = data.sum
private[this] def findSdFromSquares(s: Double, ssq: Double) = { ... }
val standardDeviation = findMySD(sum, data.map(x => x*x).sum)
Run Code Online (Sandbox Code Playgroud)

如果你需要存储一个计算供以后使用,那么private val或者private[this] val是要走的路,但如果它只是计算的中间步骤,那么上面的选项会更好.

同样地,var如果它是接口的一部分 - 例如可变矢量上的矢量坐标,那么暴露它是没有害处的.但是你应该制作它们private(更好的是:private[this],如果可以的话!)当它是一个实现细节时.

  • 您对将块中间步骤隐藏在块内的看法是什么?这在评论系统中难以格式化,但基本上是val standardDeviation = {val sumOfSquares = ...; val expectationSquared = ...; var varianceOfSample = ...; math.sqrt(data.length*varianceOfSample /(data.length -1))} (6认同)