是否可以在scala的子类中设置一个在方法中具有作用域的变量?
为什么我需要在下面的代码片段中进行解释:
abstract class SuperTask {
def doWork():Unit = {
var taskData:Option[TaskData] = None
try {
_actualWork()
}
catch {
// catch exception and do reporting using taskData variable
}
}
protected def _actualWork(): Unit
}
class FunTask extends SuperTask {
override def _actualWork(): Unit = {
//This will have data for taskData
//PROBLEM is how to set taskData of parent class from here so that if this throws exception, I can do reporting from catch in doWork method.
}
}
我想设置taskData
变量的值,以便如果_actualWork
失败,我可以进行适当的报告,重试等,这对于SuperTask
类的所有子类都是通用的
我无法在taskData
类级别定义SuperTask
变量,因为它将被共享并且在并发情况下失败。
答案 0 :(得分:1)
只需传递一个知道如何将taskData
设置为_actualWork
的闭包即可:
type TaskData = String
abstract class SuperTask {
def doWork():Unit = {
var taskData:Option[TaskData] = None
try {
_actualWork(td => taskData = td)
} catch {
case _: Throwable => println("last task data: " + taskData)
}
}
protected def _actualWork(setTaskData: Option[TaskData] => Unit): Unit
}
object FunTask extends SuperTask {
override def _actualWork(setTaskData: Option[TaskData] => Unit): Unit = {
// No problem to set taskData of parent class from here:
setTaskData(Some("Hello, world!"))
throw new Error("error")
}
}
如果现在在doWork
上调用FunTask
,从而设置taskData
并抛出错误,则会得到以下输出:
FunTask.doWork()
// output: last task data: Some(Hello, world!)
请注意,这只是“观察者”模式的一种非常便宜的变体,其中已注册的“观察者”的状态由一个局部变量组成,“通知”由对闭包{ }}。您也可以将一大堆适当的“观察者”传递到setTaskData
方法中,以便他们可以监视_actualWork
内部的情况。
答案 1 :(得分:0)
这是关于您留言下方我的最后评论:
将_actualWork
分成两个函数?第一个是Option[TaskData]
,第二个是_actualWork(taskData: Option[TaskData])
。
abstract class SuperTask {
def doWork():Unit = {
val taskData:Option[TaskData] = getData
try {
_actualWork(taskData)
}
catch {
// catch exception and do reporting using taskData variable
}
}
protected def getData(): Option[TaskData]
protected def _actualWork(taskData: Option[TaskData]): Unit
}
class FunTask extends SuperTask {
override def getData(): Option[TaskData] = Some(data)
override def _actualWork(taskData: Option[TaskData]): Unit = {
//do some work with taskData
}
}