简体   繁体   English

我如何实现具体的类,该类扩展了通过类型参数的类型别名定义类型的方法的特征

[英]How can I implement concrete class which extends trait defining a method with type by the type parameter's type alias

I would like ask for some help for advanced scala developers. 我想为高级Scala开发人员寻求帮助。 My problem is that I would like to access a type alias belonging to a type parameters of a class' parent. 我的问题是我想访问属于类的父级的类型参数的类型别名。

  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()
  }

So basically MySpecificModule extends a generic trait, and should know the type of the dispatcher method. 因此,基本上MySpecificModule扩展了通用特征,并且应该知道dispatcher方法的类型。 In this case of MySpecificModuleClass it should be MyDispatcher . 在这种情况下, MySpecificModuleClass应该是MyDispatcher But when I try to compile this code I am getting compilation error because the type of the method, is not the same as defined: A#Dispatcher , however in the reality it is. 但是,当我尝试编译此代码时,由于方法的类型与定义的类型不同,我遇到了编译错误: A#Dispatcher ,但实际上是这样。

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

             ^

I would appreciate any advice you suggest. 您的任何建议,我将不胜感激。 Thanks in advance, Gabor 在此先感谢Gabor

Resolved 解决

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()
}

I don't fully understand Scala's reasoning here, but if you get rid of type parameters, things start to work: 我在这里不完全了解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()
}

And if you really want to have those type params, you can introduce a helper trait: 如果您真的想拥有这些类型参数,则可以引入一个辅助特性:

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

class ModuleClass extends AbstractModule[MyModel,MyDispatcher]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM