Scala:带日志记录的链选项

时间:2017-03-14 14:54:18

标签: scala

我想链接一些Options来计算最终值。很简单:

def compute(aOpt: Option[String], bOpt: Option[String], 
            cFun: (String, String) => Option[String]): Option[String] = {
  for (a <- aOpt; b <- bOpt; c <- cFun(a, b)) yield a + b + c
}

但是我需要添加调试信息 - 记录丢失的数据。像下面的代码,它可以工作,但它有点笨拙:

def compute(aOpt: Option[String], bOpt: Option[String],
            cFun: (String, String) => Option[String], logger: Logger): Option[String] = {
  if (aOpt.isEmpty) {
    logger.error("a is empty")
  }
  if (bOpt.isEmpty) {
    logger.error("b is empty")
  }
  val cOpt = for ( a <- aOpt; b <- bOpt) yield cFun(a,b)
  if (cOpt.isEmpty) {
    logger.error("c is not found")
  }
  for (a <- aOpt; b <- bOpt; c <- cOpt) yield a + b + c
}

我正在寻找优雅和惯用的方法来实现它。

编辑:我改进了代码,因为在之前的版本中它有时会调用cFun两次

3 个答案:

答案 0 :(得分:3)

如果可以只记录第一个“空虚”,那么您可以为Option[T]定义隐式助手类:

implicit class LogOption[T](opt: Option[T]){
  def orLogError(msg: String)(implicit logger: Logger) = { // Require an implicit Logger
    if(opt.isEmpty) logger.error(msg); opt // Always log as error
  }
}

然后将你的理解写成:

for {
  a <- aOpt orLogError "a is empty"
  b <- bOpt orLogError "b is empty"
  c <- cFun(a, b) orLogError "c is not found"
} yield a + b + c

答案 1 :(得分:0)

def compute(aOpt: Option[String], 
            bOpt: Option[String],
            cFun: (String, String) => Option[String], logger: Logger): Option[String] = {

        val optList = List((aOpt, "a"), 
                           (bOpt, "b"), 
                           (cFun(aOpt.getOrElse(""), bOpt.getOrElse("")), "c"))

        optList.foreach(x => if(x._1.isEmpty) logger.error(x._2 + " is Empty"))

        for (a <- aOpt; b <- bOpt; c <- cFun(a, b)) yield a + b + c
   }

答案 2 :(得分:0)

@Federico Pellegatta回答让我满意 - 第一个错误对我来说已经足够了。但仅供参考,我提交了他的解决方案的修改,记录了所有错误:

pref=$(cut -d_ -f1-2 <<< "$s")