在自键型特征中访问私有成员 - 没有访问范围泄漏

时间:2015-10-02 10:45:53

标签: scala

让一个班级的私人成员可以通过类型类型的自我类型特征进行访问的直接方式是什么?

似乎protected完成了这项工作,但AFAIK也允许对子类进行访问,这对我来说是一种太宽的访问范围捆绑,除非,自我类型和子类的特征比我想。你能否对此有所了解?

代码小提琴:

trait CakeLayer {
  self: A =>
    println(a)
}

class A {
  protected val a: Int = 3
}

对我来说,当我将它用作蛋糕模式时,自我类型特征的语义与子类的语义非常不同:我不喜欢任何子类可以访问,但只有特定的自我打字特质。

1 个答案:

答案 0 :(得分:1)

我可以想到一种有点复杂的执行方式 - 它可能会激励你(或其他人)找到一个更可行的解决方案:

trait CakeLayer {
  self: A =>

  def funcToRun(a: Int) = println(a)

  runFuncOnA

}

class A {

  implicit val me: this.type = this

  private val a: Int = 3

  protected def runFuncOnA(implicit cl: CakeLayer) = cl.funcToRun(a)
}

这强制了A的任何子类都没有扩展CakeLayer试图调用runFuncOnA不会编译:

scala> val aa = new A // Doesn't call 'runFuncOnA' - OK
aa: A = A@6a997956

scala> val aa = new A { runFuncOnA } // Doesn't extend CakeLayer - bad!
<console>:28: error: could not find implicit value for parameter cl: CakeLayer
       val aa = new A { runFuncOnA }
                        ^

scala> val aWithCL = new A with CakeLayer // Extends CakeLayer, so calling 'runFuncOnA' is OK here:
3
aWithCL: A with CakeLayer = $anon$1@59bf1b79

基本上,trait调用父类来调用回调特征上定义的特定方法,并传递私有值。