2013-12-11 24 views
1

我對「消息」性狀的一組消息的鹼:Scala的性狀子類約束

trait Message{ 
    id: Int 
} 

case class AckMsg(id: Int) extends Message 
case class NackMsg(id: Int) extends Message 

和具有一些功能,以把它們作爲參數:

def replyAck(ack: AckMsg) = { ... } 

def replyNack(nack: NackMsg) = { ... } 

當我定義一些更高層次的功能來利用這些功能,我遇到了:

def replyingMsg(fun: Message => Unit): Unit = { ... } 

replyingMsg(replyAck(AckMsg(id))) //compiling error here! 

編譯器不喜歡事實上,我有(消息=>單元),但傳遞(AckMsg =>單元)

那麼,如何才能我在replyingMsg,定義類似的東西:

def replyingMsg(fun: M <: Message => Unit) //imagery code!!! 

上面的代碼是錯誤的:

  1. 出於某種原因,一旦涉及<:消息不能被一個特點,需要一個類
  2. <:似乎並不正確描述的情況

我該如何告訴編譯器,我正在傳遞一個特性的子類? 請有人對複雜的類型系統進行一些闡述。

回答

1

我想你想以下幾點:

def replyingMsg[T <: Message](fun: T => Unit): Unit = { } 

說好玩是從T到單位的功能,使得T是消息的子類。我不打算評論目前使用Trait和抽象類的設計的優點,但是如果其他人有想法,我會很感興趣。

+0

我確實遵循了推薦的Akka文檔格式。有一個密封的特質,然後有一套信息從它延伸。只是好奇,使用抽象類有什麼好處呢? – Joyfulvillage

+0

我自己在這種情況下不知道。在Scala中,我迷失於多種對象建模方式 - 在這種情況下,它看起來像一個經典的對象層次結構,我認爲特徵更像Java接口。 – jimmyb

+0

對於其他觀衆來說,這個答案完美解決了這個問題。謝謝jimmyb。我認爲特徵遠遠超過Java接口,而我在其他人中看起來越來越多的是Scala代碼。特別是當涉及到蛋糕模式時,我認爲這有點濫用,但不能否認讓我的開發生活更容易。 (而且代碼更乾淨) – Joyfulvillage

1

您有一個問題,即第一類函數(replyAck _)和(replyNack _)實際上是Function1 [-Message,+ Unit]類型的特徵,因此它們處於Message的控制位置。

如果你仍然想遵循這個模式,並使用方法def replyingMsg(fun:Message => Unit):單位沒有改變,你可以用很多方法解決這個問題。例如使用pf:

def replyingMsg(fun: Message => Unit): Unit = {println("success")} 

scala> def replyAck: Message => Unit = {case AckMsg(id) => Unit} 
replyAck: Message => Unit 

scala> replyingMsg(replyAck) 
success