代码之家  ›  专栏  ›  技术社区  ›  Troy Daniels

在scala中使用对象绑定类

  •  2
  • Troy Daniels  · 技术社区  · 6 年前

    我试图编写代码来包装一个建模库。模型的简化版本如下:

    class Model() {
        class Thing(val name: String) {
            private[Model] val foo = name + " foo "
    
            def join(other: Thing) = new Thing(foo + other.foo)
        }
    
        def thing(name: String) = new Thing(name)
    }
    

    foo 实际上是与 Model . 使用 Thing 从两个不同的 模型

    我有几个scala测试调用 model.thing 使用它们,按需要工作。

    然后我开始在上面写一个抽象层:

    class Widget(name: String)(implicit val model: Model) {
        val thing = model.thing(name)
    }
    
    class CompoundWidget(name: String, children: Seq[Widget])(implicit val model: Model) extends Widget(name)
    {
        val combo =
            children.sliding(2).foreach(pair => pair(0).thing join pair(1).thing)
    }
    

    无法编译:

    Simple.scala:20: error: type mismatch;
      found   : (some other)_1.type(in value $anonfun)#model.Thing where type (some other)_1.type(in value $anonfun) <: com.proteus.orchestration.mediatorModule.scheduling.Widget with Singleton
      required: _1.type(in value $anonfun)#model.Thing where type _1.type(in value $anonfun) <: com.proteus.orchestration.mediatorModule.scheduling.Widget with Singleton
             children.sliding(2).foreach(pair => pair(0).thing join pair(1).thing)
                                                                    ^
    

    Seq[Widget] 我进来用同样的 模型 对于每个元素,它都会给出一个错误。

    有办法解决这个问题吗?似乎可以工作(但我还没有尝试)的是创建一个类来保存整个抽象层,这样编译器就可以看到我总是使用 模型 . 但是,这意味着,无论它增长多大,我都需要将所有代码保存在一个文件中,这最终会变得很难处理。

    我的背景是一个开始使用Scala的Java程序员,所以我可能只需要向我解释一下Scala方式(tm)。

    1 回复  |  直到 6 年前
        1
  •  3
  •   Brian McCutchon    6 年前

    你玩的是 dependent types . 一种方法是确保 Widget CompoundWidget 参考相同的 Model

    class View(val model: Model) {
      class Widget(name: String) {
        val thing = model.thing(name)
      }
    
      class CompoundWidget(name: String, children: Seq[Widget]) extends Widget(name) {
        val combo =
            children.sliding(2).foreach(pair => pair(0).thing join pair(1).thing)
      }
    }
    

    我称之为 View 因为我想你会 MVC

    val view = new View(new Model)
    import view._
    new Widget("foo")  // No need to specify View or Model