【问题标题】:How can I implement concrete class which extends trait defining a method with type by the type parameter's type alias如何实现扩展特征的具体类,该特征通过类型参数的类型别名定义具有类型的方法
【发布时间】:2015-06-25 16:29:26
【问题描述】:

我想为高级 scala 开发人员寻求一些帮助。我的问题是我想访问属于类父类的类型参数的类型别名。

  case class MyModel(foo: String = "bar")

  case class MyDispatcher()

  trait Module[M, D] {
    type Dispatcher = D
    type Model = M
  }

  trait MySpecificModule[A <: Module[_, _]] {
    def dispatcher(): A#Dispatcher
  }

  class ModuleClass extends Module[MyModel, MyDispatcher] {
    //...
  }

  class MySpecificModuleClass extends MySpecificModule[ModuleClass] {
    override def dispatcher(): MyDispatcher = MyDispatcher()
  }

所以基本上MySpecificModule 扩展了一个通用特征,并且应该知道dispatcher 方法的类型。在这种MySpecificModuleClass 的情况下,它应该是MyDispatcher。但是当我尝试编译这段代码时,我得到了编译错误,因为方法的类型与定义的不同:A#Dispatcher,但实际上它是。

Error:(21, 18) overriding method dispatcher in trait MySpecificModule of type ()_$2;
 method dispatcher has incompatible type
    override def dispatcher(): MyDispatcher = MyDispatcher()

             ^

如果您提出任何建议,我将不胜感激。提前致谢, 嘉柏

已解决

case class MyModel(foo: String = "bar")

case class MyDispatcher()

trait AbstractModule {
  type Dispatcher
  type Model
}

trait Module[M, D] extends AbstractModule {
  type Dispatcher = D
  type Model = M
}

trait MySpecificModule[A <: AbstractModule] {
  def dispatcher(): A#Dispatcher
}

class ModuleClass extends Module[MyModel, MyDispatcher] {
  //...
}

class MySpecificModuleClass extends MySpecificModule[ModuleClass] {
  override def dispatcher(): MyDispatcher = MyDispatcher()
}

【问题讨论】:

    标签: scala generics type-erasure type-parameter type-alias


    【解决方案1】:

    我不完全理解 Scala 的推理,但如果你去掉类型参数,事情就开始起作用了:

    case class MyModel(foo: String = "bar")
    
    case class MyDispatcher()
    
    trait Module {
      type Dispatcher
      type Model
    }
    
    trait MySpecificModule[A <: Module] {
      def dispatcher(): A#Dispatcher
    }
    
    class ModuleClass extends Module {
      type Model = MyModel
      type Dispatcher = MyDispatcher
      //...
    }
    
    class MySpecificModuleClass extends MySpecificModule[ModuleClass] {
      override def dispatcher(): MyDispatcher = MyDispatcher()
    }
    

    如果你真的想要拥有这些类型参数,你可以引入一个辅助特征:

    trait AbstractModule[M, D] extends Module {
      type Model = M
      type Dispatcher = D
    }
    
    class ModuleClass extends AbstractModule[MyModel,MyDispatcher]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-04
      • 1970-01-01
      • 2018-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多