首页 > 解决方案 > 如何在其他方法中设置局部变量

问题描述

是否可以在 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因为它将被共享并在并发的情况下失败。

标签: scala

解决方案


只需传递一个知道如何设置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")
  }
}

如果您现在调用doWorkon FunTask,它会设置taskData并抛出错误,您会得到以下输出:

FunTask.doWork() 
// output: last task data: Some(Hello, world!)

请注意,这只是“观察者”模式的一个非常便宜的变体,其中您注册的“观察者”的状态由一个局部变量组成,而“通知”由对闭包的调用组成setTaskData。您也可以将一大堆适当的“观察者”传递给该_actualWork方法,以便他们可以监视内部发生的事情_actualWork


推荐阅读