【问题标题】:Decorate by Delegation (like kotlin) in ScalaScala 中的委托装饰(如 kotlin)
【发布时间】:2022-01-17 12:59:02
【问题描述】:

在 kotlin 中有 'Decorate by Delegation' 模式。有没有办法在 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()

}

【问题讨论】:

    标签: scala kotlin decorator


    【解决方案1】:

    据我所知,在 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 })
    

    (见scastie

    正如您在 export 中看到的那样,您甚至不必创建单独的名称 class(尽管您可以根据需要创建),也不必在装饰者和被装饰者之间建立任何类型的子类型关系结果将导出所有必要的定义或手动实现。

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

    【讨论】:

    • 嗯,它与 kotlin 派生不同。它相似但不一样。事实上,如果我创建 Bar 作为 Foo 的扩展,我不能覆盖 b(在 kotlin 中我可以)。还是我错了? (scastie)
    • 您可以手动排除冲突值 (scastie)
    • 代码示例有点混乱,但是使用这个导出你至少可以实现我想要实现的行为,这很酷,可惜它在scala2中不存在
    • 基本上,exportimport 的对偶:您可以按名称导出:export bar.a,您可以分组导出 export bar.{ a, b }, baz.c。重命名事物:export foo.{ a => baz },您可以使用通配符:export bar._(从bar 导出所有内容)、export bar.{ b => _, _ }(导出所有除了 b)。您可以在import 中使用的所有功能将内容放入您的范围,您可以使用export 将内容暴露在外面。可能你之前没用过import foo.{ bar => _, _ }
    猜你喜欢
    • 1970-01-01
    • 2021-04-07
    • 1970-01-01
    • 1970-01-01
    • 2017-11-28
    • 2011-03-29
    • 2018-05-07
    • 2015-09-03
    • 2012-11-03
    相关资源
    最近更新 更多