考虑以下Akka演员。该actor的实现应该覆盖并实现handleMessage(message: T)
。此实现应在其最后一行调用executeQueryLookup
abstract class BaseQueryLookupActor[T, U] extends Actor {
def receive = {
case message: T => handleMessage(message)
case message => unhandled(message)
}
def handleMessage(message: T) // Abstract method
def executeQueryLookup(cacheName: String, queryName: String, params: Map[String, String]) {
// Concrete method that contains query logic
}
}
我意识到有多种方法可以在不使用任何Scala功能概念的情况下实现这一点,但我认为也可以使用部分函数或currying以某种方式实现这一点。 如果是这样,我将如何实现这一目标?
答案 0 :(得分:1)
我不确定我会效仿,但是它可以定义
def handleMessage(message: T): (String, String, Map[String, String])
并在基类中自己调用executeQueryLookup
,例如
def receive = {
case message: T =>
val (cacheName, queryName, params) = handleMessage(message)
executeQueryLookup(cacheName, queryName, params)
case message => unhandled(message)
}
答案 1 :(得分:1)
如果将它留给子类来实现一个方法,并调用该方法,那么超类就没有什么可以强制执行子类中的实现做一些特定的操作。这与currying或partial functions无关。
您的actor会遇到另一个问题,因为通用类型T
在JVM上被删除:在运行时T = java.lang.Object
。因此,匹配将始终成功,并且永远不会调用第二种情况。在创建actor和每条消息时,您都必须传递type tags。粗略的近似是使用classTag
,因为每个JVM对象都有.getClass
方法,但这只会匹配最外面的类型,如果你想要区分{{1},它将无济于事来自List[Int]
。