scala - 如何在其他方法中设置局部变量
问题描述
是否可以在 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
因为它将被共享并在并发的情况下失败。
解决方案
只需传递一个知道如何设置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
on FunTask
,它会设置taskData
并抛出错误,您会得到以下输出:
FunTask.doWork()
// output: last task data: Some(Hello, world!)
请注意,这只是“观察者”模式的一个非常便宜的变体,其中您注册的“观察者”的状态由一个局部变量组成,而“通知”由对闭包的调用组成setTaskData
。您也可以将一大堆适当的“观察者”传递给该_actualWork
方法,以便他们可以监视内部发生的事情_actualWork
。
推荐阅读
- python - Doc2Vec相似性小语料测试
- javascript - ReactJS:如何让这个图像轮播运行更流畅?
- javascript - 反射跨站脚本
- for-loop - 承诺函数中的for循环
- .htaccess - 如何解决此问题:规则集无法转换为等效的 IIS 格式,因为不支持控制流标志(C、S、N)
- r - 将 NULL 参数替换为“0”
- r - 在某些条件下将一个变量的级别折叠为另一个变量
- c - 如何仅在整数的最高有效半部分反转位,而另一半(最低有效位)保持不变?
- python - 如何检查python中元素列表中的空元素
- python - 我想从python中的文本文件中删除某些字符串