簡體   English   中英

Scala作為要混合的參數傳遞特征

[英]Scala passing in traits as parameters to be mixed in

我(缺少更好的術語)封裝構造對象的工廠方法:

def createMyObject = new SomeClass(a, b, c, d)

現在,根據上下文,我需要將一個或多個特征混合到SomeClass中:

new SomeClass with Mixin1

要么

new SomeClass with Mixin2 with Mixin3

不是為每個“類型”實例化創建多個單獨的工廠方法,而是如何傳入要混合的特征,以便可以使用單個方法完成? 或者也許有一個很好的模式,結構不同?

我想保持封裝,所以我寧願不讓每個消費者自己創建這個類。

如果只需要mixins而沒有方法覆蓋,你可以只使用類型類:

trait Marker
class C[+T <: Marker] { def b = 1 }

trait Marker1 extends Marker
implicit class I1[T <: Marker1](c: C[T]) {def a = 6 + c.b}

trait Marker2 extends Marker
implicit class I2[T <: Marker2](c: C[T]) {def a = 5 + c.b}

trait Marker3 extends Marker
implicit class I3[T <: Marker3](c: C[T]) {def k = 100}

trait Marker4 extends Marker3
implicit class I4[T <: Marker4](c: C[T]) {def z = c.k + 100} //marker3's `k` is visible here

scala> def create[T <: Marker] = new C[T]
create: [T <: Marker]=> C[T]


scala> val o = create[Marker1 with Marker3]
o: C[Marker1 with Marker3] = C@51607207

scala> o.a
res56: Int = 7

scala> o.k
res57: Int = 100

scala> create[Marker4].z
res85: Int = 200

但它不適用於create[Marker1 with Marker2].a (模糊含義),因此這里沒有線性化。 但是如果你想混合一些方法(比如在javascript的原型中)並且可能注入一些東西 - 似乎沒問題。 您還可以通過向C,I1,I2等添加一些特征將其與傳統的線性化混合相結合。

您可以根據上下文以不同方式實例化類。

def createMyObject =
  if (context.foo)
    new SomeClass
  else
    new SomeClass with Mixin1

但是,如果消費者是那些知道應該混入的特征的消費者,那你為什么不在那里實例化呢?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM