2015-04-02 63 views
0

我有這個用例我無法解決。 我想到了消息傳遞編程的環境。 有兩個主要概念,事物和環境: 事情就像現實世界它們可以是被動或主動的,他們可以發送和接收消息。環境可以實現事物之間的溝通。 我想出了這個解決方案:運行時Scala類檢查

/**** **** Thing.scala/

abstract class Thing(environment : Environment){ 
    val uniqueName : String 
    require(environment != null) 
} 

/**** **** ActiveThing.scala/

trait ActiveThing extends Thing { 
    environment.register(this) 
    type inputType 
    type outputType 
    def receiveMessage(message : Message[inputType]) : outputType 
    def canReceiveMessage(subject : String) : Boolean 
}  

/**** **** Environment.scala/

trait Environment { 
    private var _passiveThings = List[PassiveThing]() 
    private var _activeThings = List[ActiveThing]() 

    def activeThings = _activeThings.toSeq 
    def passiveThings = _passiveThings.toSeq 
    def register(p : PassiveThing) = _passiveThings +:= p 
    def register(a : ActiveThing) = _activeThings +:= a 
    def unicastRequest[T,K](from : String, message : Message[T], to : String) : K 
} 

/**** **** Message.scala/

case class Message[T](subject : String, body : T) 

但是當我嘗試實際執行:

/**** **** EchoActiveThing.scala/

class EchoActiveThing(implicit inj: Injector) extends Thing()(inj) with ActiveThing { 
    type inputType = String 
    type outputType = String 
    val uniqueName : String = "Echo" 
    def receiveMessage(message : Message[inputType]) : outputType = { 
    message.body 
    } 
    def canReceiveMessage(subject : String) : Boolean = { 
    true 
    } 
} 

/**** **** BasicEnvironment.scala/

class BasicEnvironment extends Environment { 
    def unicastRequest[T,K](from : String, message : Message[T], to : String) : K = { 
    activeThings.filter{ x => 
     x.inputType == T && 
     x.outputType == K && 
     x.canReceiveMessage(message) && 
     activeThings.contains(to.uniqueName) 
    } 
    } 
} 

但它並沒有編譯。我想我沒有以正確的方式處理這個問題! 謝謝

回答

1

x.inputType是一個類型投影,而不是一個變量。它不能與==進行比較,這就是代碼無法編譯的原因。要在運行時比較類型,您可以使用TypeTag[T]

case class Holder[T](t: T) 

def areEqualTypes[A, B](a: Holder[A], b: Holder[B]) 
         (implicit tagA: TypeTag[A], tagB: TypeTag[B]) = { 
    tagA == tagB 
} 

val (h1, h2, h3) = (Holder("Foo"), Holder("Bar"), Holder(5)) 
println(areEqualTypes(h1, h1)) //true 
println(areEqualTypes(h1, h2)) //true 
println(areEqualTypes(h1, h3)) //false 

在這個例子中類型標籤一起用函數的參數隱式傳遞。這次您可以使用==,因爲tagAtagBTypeTag[A]TypeTag[B]類的實例。