我尝试创建一个类的实例,并根据某些条件混合某些特征。所以鉴于:
class Foo
trait A
trait B
我可以做类似
的事情if (fooType == "A")
new Foo with A
else if (footType == "B")
new Foo With B
这对于像这样的简单案例来说效果很好。我的问题是多个特征可以基于其他条件混合到同一个实例中,并且最重要的是,实例化的类具有相当多的参数,因此这会导致非常难看的条件块。
我想做的是确定之前要混合的特征(我知道这不是合法的scala代码):
val t1 = fooType match {
case "a" => A
case "b" => B
}
val t2 = fooScope match {
case "x" => X
case "y" => Y
}
new Foo with t1 with t2
其中A,B,X和Y都是先前定义的特征,fooType和fooScope是我的函数的输入。我不确定我能做些什么,与上面的内容有些类似,但我们不胜感激。
由于
答案 0 :(得分:2)
我相信你想做的事是不可能的。在Scala中,必须在编译时知道对象的类型,因此new Foo with A
有效但new Foo with t1
不会,因为t1
仅在运行时解析。
答案 1 :(得分:0)
混合使用的几个想法......
由于复杂的代码中充满了您所说的条件,请将这些条件放在一起列出可能的组合。然后可以使用此列表创建所有类。非常简单的例子:
(for(a <- Seq("A", "B"); b <- Seq("X", "Y")) yield
s"class Foo$a$b extends $a with $b").mkString("\n")
将产生以下内容:
class FooAX extends A with X
class FooBX extends B with X
class FooAY extends A with Y
class FooBY extends B with Y
然后简单地说:
val ax = new FooAX()
这很好,因为它的键入非常强大,每个人都会确切地知道它到底是什么类型而没有太多的演员/推理头痛。
这里有一个有趣的非反射/类加载器技术:
https://github.com/b-studios/MixinComposition
将traits作为参数,然后简单地委托给适当的特征。