【问题标题】:Reference a constructor argument from a trait从 trait 引用构造函数参数
【发布时间】:2011-10-10 12:11:27
【问题描述】:

在 Scala 中,特征是否可以引用它所混入的类的命名构造函数参数?下面的代码无法编译,因为 ModuleDao 的构造函数参数不是特征中定义的 val。如果我在构造函数参数之前添加val 以使其公开,它与特征中的匹配并编译,但我不希望将其设置为val

trait Daoisms {
  val sessionFactory:SessionFactory
  protected def session = sessionFactory.getCurrentSession
}

class ModuleDao(sessionFactory:SessionFactory) extends Daoisms {
  def save(module:Module) = session.saveOrUpdate(module)
}

/* Compiler error:
class ModuleDao needs to be abstract, since value sessionFactory in trait Daoisms of type org.hibernate.SessionFactory is not defined */

// This works though
// class ModuleDao(val sessionFactory:SessionFactory) extends Daoisms { ... }

【问题讨论】:

  • 为什么不将其设置为val?您已经在Daoism 上这样做了,那么为什么不在ModuleDao 上这样做呢?问题在于,您声明sessionFactory 的方式实际上是私有的——其他人无法看到它。

标签: scala constructor scala-2.9 traits


【解决方案1】:

如果您唯一关心的是使其成为 val 是可见性,您可以像这样使 val 受到保护:

scala> trait D { protected val d:Int
     | def dd = d
     | }
defined trait D

scala> class C(protected val d:Int) extends D
defined class C

scala> new C(1)
res0: C = C@ba2e48

scala> res0.d
<console>:11: error: value d in class C cannot be accessed in C
 Access to protected value d not permitted because
 enclosing class object $iw in object $iw is not a subclass of 
 class C in object $iw where target is defined
              res0.d
                   ^

scala> res0.dd
res2: Int = 1

【讨论】:

  • 谢谢 - 为了简洁起见,我可以选择 val 并接受它是公开可见的。它仅在内部使用,因此在这种情况下 public 并不太公开。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-19
  • 2020-02-21
  • 2015-05-08
  • 1970-01-01
  • 2018-10-03
  • 2015-02-03
  • 2016-03-11
相关资源
最近更新 更多