ソケットを介して接続されたクライアントサーバーアプリケーションがあります。私のMessageHandlerクラスは、着信メッセージと発信メッセージの処理を担当します。リクエストとコールバックを満たすために必要な引数を渡します。これらは、レスポンスが受信された後に呼び出されます。コールバックを一意のリクエスト識別子を使用してハッシュマップに保存します。応答を受信すると、ハッシュマップからコールバックを取得し、それを呼び出して、応答を引数として渡します。これがコードです
class MessageHanlder {
val callbacks = new HashMap[String, (AnyRef) => Unit]
def sendAuthRequest(login: String, password: String, callback: Option[(AnyRef) => Unit]) {
val requestId = generateRequestId()
// create a packet with requestId, login and password
// send the packet
if(callback.isDefined) callbacks += ((requestId, callback.get))
}
private def generateRequestId() = // returns random string
def handleAuthResponse(authResponse: AuthResponse) {
val requestId = authResponse.requestId
val callbackOption = callbacks.get(requestId)
if(callbackOption.isDefined) callbackOption.get(authResponse)
}
def sendServerInfoRequest(callback: Option[(AnyRef) => Unit]) {
val requestId = generateRequestId()
// create a packet with requestId
// send the packet
if(callback.isDefined) callbacks += ((requestId, callback.get))
}
def handleServerInfoResponse(serverInfoResponse: ServerInfoResponse) {
val requestId = serverInfoResponse.requestId
val callbackOption = callbacks.get(requestId)
if(callbackOption.isDefined) callbackOption.get(serverInfoResponse)
}
私の問題は、コールバックの引数タイプです。ServerInfoResponse、AuthResponse、またはその他の応答タイプにすることができます。各応答には、コールバックからアクセスしたい独自のフィールドのセットがあります。コールバックをハッシュマップに保存するには、引数の型をAnyRefとして一般化する必要があります。したがって、コールバックでは、AnyRefを次のような具象型にキャストする必要があります
val serverInfoCallback = (response: AnyRef) => {
val serverInfoResponse = response.asInstanceOf[ServerInfoResponse] // explicit cast
val name = serverInfoResponse.name
val numberOfCores = serverInfoResponse.numberOfCores
// so on
}
キャストを回避する方法はありますか?または、コールバックシステムを実装するためのより正しい方法はありますか?
ありがとう!