错误:协变类型C出现在类型的不变位置?

时间:2016-02-12 01:44:26

标签: scala

我已经看到了这个例外的所有其他答案,但我认为他们没有解决我的问题,或者我可能不理解。

我尝试创建一个类型类,以便将Command的实现提取到CommandHandler s

object TestMe extends App {

  //COMMAND
  trait Command

  trait UserCommand extends Command

  case class CreateUserCommand(username: String) extends UserCommand

  //COMMAND HANDLER
  trait CommandHandler[C <: Command] {
    def processCommand(command: C): Boolean
  }

  trait UserCommandHandler[+C <: UserCommand] extends CommandHandler[C]

  implicit object CreateUserCommandHandler extends UserCommandHandler[CreateUserCommand] {
    override def processCommand(command: CreateUserCommand): Boolean = true
  }


  //Running UserCommand
  def processCommand[C <: UserCommand](command: C)(implicit commandHandler: UserCommandHandler[C]) =
    commandHandler.processCommand(command)

  val createUserCommand: UserCommand = CreateUserCommand("username")

  println(processCommand(createUserCommand))
}

但我一直得到以下异常

covariant type C occurs in invariant position in type [+C <: TestMe.Command]TestMe.CommandHandler[C] {

} of trait UserCommandHandler
  trait UserCommandHandler[+C <: Command] extends CommandHandler[C]
        ^

1 个答案:

答案 0 :(得分:1)

UserCommandHandler中的类型C是协变的,但CommandHandler中的类型C是不变的,因此您无法将C类型从UserCommandHandler传递给CommandHandler

所以你有两个选择 -

  1. CommandHandler中的C类特征也应该是协变的。

    trait CommandHandler[+C <: Command] {
      def processCommand[B >: C](command: B): Boolean
    } 
    
  2. UserCommandHandler中的C类型应该是不变的

    trait UserCommandHandler[C <: UserCommand] extends CommandHandler[C]    
    
  3. 看看你的其余代码,不变性似乎已经足够好了。使CommandHandler协变也需要对代码进行其他更改