如何在具有相同名称但不同类型的隐式val中混合特征?

时间:2013-03-11 19:57:12

标签: scala traits

我有来自两个第三方图书馆的特征,我正试图融入我自己的特质。它们都定义了名为implicit val的{​​{1}}。

但是,它们的类型不同 - 一个是SLF4J log,另一个是Spray Logger(实际上是Akka LoggingContext)。事实上,第二个特征来自Spray,它是LoggingAdapter。 (不是你可以在Github上找到的最新版本,它不再具有HttpServer)。

所以,这是代码(一个库重命名,因为它是专有的,Spray代码被剪切以显示相关部分):

val

这不会编译。编译器抱怨:

  

错误:在类型的特征HttpService中覆盖延迟值日志   带有spray.util.LoggingContext的java.lang.Object;懒惰值登录   trait LibraryOne $ class org.slf4j.Logger需要`覆盖'   修饰符特征DemoService使用LibraryOne {

扩展HttpService

我有什么方法可以将这两个特征混合在一起吗?

1 个答案:

答案 0 :(得分:4)

据我所知,唯一的方法是创建CombinedLogger

class CombinedLogger(l1:Logger, l2:LoggingAdapter) extends Logger with LoggingAdapter {
   // proxy methods to the correct logger
}

如果两个记录器都被声明为def,您可以像这样使用它:

override def log = new CombinedLogger(super[LibraryOne].log, super[HttpService].log)

在这种情况下,它很棘手,因为它们被定义为val,它告诉Scala编译器它们是一个不会改变的单个值。因此,它不允许你拨打super.log。所以你需要复制被覆盖的特征的逻辑。

在这种情况下,另一个棘手的部分是你需要代理CombinedLogger中的50多种方法。