Scala 中的委托装饰(如 kotlin)

Ehu*_*Lev 3 scala decorator kotlin

在 kotlin 中有“委托装饰”模式。有没有办法在 Scala 中以优雅的方式实现它。

这是一个 kotlin 代码示例:

interface Doo{
    fun a(): Unit
    fun b(): Unit
}

class Goo:Doo {
    override fun a() {
        println("goo a")
    }

    override fun b() {
        println("goo b")
    }
}

class Moo(doo: Doo):Doo by doo{
    override fun b() {
        println("mooooooo")
    }
}

fun main() {
    val m = Moo(Goo())
    m.a();m.b()

}
Run Code Online (Sandbox Code Playgroud)

Mat*_*zok 5

据我所知,在 Scala 2 中,你无法实现这一点。然而,在 Scala 3 中可以使用export

trait Foo {
  
  def a: Int
  
  def b: String
}

trait Bar {
  
  def a: Int
}

def decorateAsFoo(bar: Bar): Foo = new Foo {
  export bar._ // export all bar methods/values/types in this Foo impl
  
  override def b: String = "decorated"
}


decorateFoo(new Bar { override def a: Int = 10 })
Run Code Online (Sandbox Code Playgroud)

(参见斯卡斯蒂

正如您所看到的,export您甚至不必创建单独的名称class(尽管如果您愿意,也可以),也不必在装饰器和装饰器之间有任何类型的子类型关系,只要结果具有所有必要的手动导出或实施的定义。

在 Scala 2 中(据我所知),您可以信赖的最好方法是通过像Chimney这样的库将一种数据类型转换为具有类似模式的另一种数据类型。我不知道有任何库在存储行为的类之间进行这种转换。

  • 您可以手动排除冲突的值([scastie](https://scastie.scala-lang.org/sT5DXHjhTZuuvwpNv6QaOA)) (3认同)
  • 基本上,“export”与“import”具有双重作用:您可以按名称导出:“export bar.a”,您可以对导出进行分组“export bar.{ a, b }, baz.c”。重命名:`export foo.{ a => baz }`,您可以使用通配符:`export bar._`(从`bar`导出所有内容),`export bar.{ b => _, _ }`(导出所有_除了_`b`)。您可以在“导入”中使用的所有功能将内容放入您的范围内,您可以与“导出”一起使用以将内容公开到外部。也许您之前没有使用过 `import foo.{ bar => _, _ }` 。 (3认同)