Scala 2.11.2 中 Scala 中的动态混音



我对Scala比较陌生。我想将动态混合与一个类一起使用(它的名字,我把它作为字符串(。

class Foo extends Baz {
}
trait bar {
}
trait biz {
}
var className = "Foo"

我想要类似的东西

var instance = (object of class className) with bar with biz

我已经阅读了 Scala 中动态混合的解决方案 - 这可能吗?但是该解决方案中使用的解释器类已被弃用(在scala 2.11中(,并且它没有compileAndSaveRun方法。代码也知道类是什么。

我尝试使用Imain类。它也没有compileAndSaveRun方法。我研究了 compileSourcesKeepingRun 方法。我不知道如何使用它。

我能做些什么吗?

可以使用反射来实现某种有限形式的动态组合。给定类f: Foo的实例和特征b: bar的实例,Foo with bar可以通过委托给底层对象来实现fb。假设FooBar有以下抽象方法:

abstract class Foo {
  def foo: Int
}
trait Bar {
  def bar: String
}

然后,我们可以给出一个通过委托Foo with Bar的实例:

val f: Foo = ...
val b: Bar = ...
val both = new Foo with Bar {
  def foo = f.foo
  def bar = b.bar    
}

这本质上是我的mixin合成库自动为您所做的。它提供了方法

def mix[A, B](a: A, b: B): A with B

可用于通过简单的mix(f, b)调用来撰写fb。该库采用使用类型类的方法

trait With[A, B] {
  def apply(a: A, b: B): A with B
}

作为可以组成AB的证据。这样做的好处是,提供此证据的多种方式是可能的:(1( 使用反射,(2( 使用宏和 (3( 为特定参数手动指定 With 的实例 AB

但是,如前所述,这种形式的动态组合是有限的。由于此方法基于转发,因此无法获得正确的方法后期绑定。此限制对于基于转发的所有解决方案(如修饰器模式(都是通用的。此外,通过自类型注释表达对其他组件的依赖关系也是行不通的,因为各个特征必须单独实例化,并且不能有未满足的依赖关系。

相关内容

  • 没有找到相关文章