2013-12-11 4 views
0

я следующий код:Понимание разница в Scala

trait DestinationBinding[T <: Actor] { 
def resolve(implicit context: ActorContext, manifest: scala.reflect.ClassTag[T]): ActorRef = { 
    println(s"creating destination binding actor of:$name") 
    context.actorOf(Props[T], name) 
} 

def name: String = manifest.runtimeClass.getSimpleName 
} 

Это в основном только простой способ для создания актеров. И после некоторых реализаций.

case class BlackHoleBinding extends DestinationBinding[BlackHoleDeliveryAgent] 

Где BlackHoleDeliveryAgent актер

Есть также некоторые сообщения:

case class Delivery[T <: Actor](message: Any, binding: DestinationBinding[T]) 

Проблема возникает, когда я хочу, чтобы шаблон матча над тем:

Note: com.elemica.erc.BlackHoleDeliveryAgent <: akka.actor.Actor (and BlackHoleBinding <: DestinationBinding[BlackHoleDeliveryAgent]), but trait DestinationBinding is invariant in type T. 
[error] You may wish to define T as +T instead. (SLS 4.5) 
[error]  case Delivery(message, binding: BlackHoleBinding) => { 
+0

Нам действительно нужно увидеть больше кода, можете ли вы дать нам полное выражение соответствия? Угадай, основываясь на том, что у вас есть, похоже, что вы пытаетесь сопоставить значение 'Delivery [Actor]' с 'Delivery [BlackHoleDeliveryAgent]', которое всегда будет терпеть неудачу, потому что 'Delivery [BlackHoleDeliveryAgent]' не является подтипом ' Доставка [Actor] '. Если вы сделали так, как это предлагает, и объявите T как + T, это будет подтип, и совпадение будет возможно. – wingedsubmariner

+0

Забыл упомянуть, что он ударит другой ошибкой, опубликует его. – Lukasz

ответ

0

Разница всегда немного сложно справиться; проблема в том, что у вас есть BlackHoleDeliveryAgent - это подкласс Актера, но это не означает, что DestinationBinding [BlackHoleDeliveryAgent] является подклассом DestinationBinding [Актер] и, следовательно, любого другого DestinationBinding [T <: Актер]; это связано с тем, что DestinationBinding инвариантен относительно T.

Если вы вносите свой вариант назначения DestinationBinding в T, это будет означать, что DestinationBinding [T] будет подклассом DestinationBinding [S], если T является подклассом S (который является что вы хотите в этом случае). Вы можете сделать это, определив DestinationBinding следующим образом:

trait DestinationBinding[+T <: Actor] {... } 

Ради знаний, есть также противопоказаны вариант аннотаций, который будет делать противоположное, так что если T является подклассом S DestiniationBinding [S] будет подклассом T. Это делается следующим образом:

trait DestinationBinding[-T <: Actor] { ... } 
Смежные вопросы