Scala - 返回既不是True也不是False的布尔值

时间:2017-05-01 20:10:13

标签: scala

我已经阅读了为什么使用" null"在斯卡拉不鼓励。但是我遇到了一个方法问题,我想回复一个"空的"布尔值在某些条件下既不是真的也不是假的。

def exampleMethod (query: String): Boolean =
{  
  var result: Boolean = false
  try
  { 
     //This will take the input query and return "true" or "false" 
     //depending on the state of the database
     result = boolQueryResult.evaluate()
     return result
  }
  catch
  {
     case e: Throwable => logger.info(e.toString)
  }
  logger.info("Something is wrong! I want to return a boolean with nothing in it!")
  return result
  }

在上面的代码中,我使用的evaluate()方法将返回true或false,然后该值将在Boolean中返回。但是如果出现问题并且执行了catch块,我想返回一个不是true或false的布尔值,以显示输入字符串有错误。在此方法的当前版本中,布尔值初始化为" false,"这是不理想的,因为它表明evaluate()返回false,而不是执行了catch块。有没有办法以一种不会返回的方式初始化这个变量" true"或"假"如果抛出异常?

4 个答案:

答案 0 :(得分:3)

@bipll是对的。 Option[Boolean]是Scala实现您想要的方式。这就是它的完成方式。

def exampleMethod(query: String): Option[Boolean] =
  try {
    Some(boolQueryResult.evaluate())
  } catch {
      case e: Throwable => logger.info(e.toString)
                           None
  }

答案 1 :(得分:3)

虽然其他答案提示Option(返回Some(true)Some(false)None,但在None的情况下会丢失错误消息因此,我建议改为使用TryEither

示例可能如下所示:

import scala.util.{Either, Left, Right}
import scala.util.{Failure, Success, Try}
// Notice the return type: we either return the error as a Left(...), or a Right(boolean result)
def exampleMethod (query: String): Either[Throwable, Boolean] = {
  // Is this where you meant to use `query`? It's not used in your original post
  Try(boolQueryResult.evaluate(query)) match {
    case Success(result) => Right(result)
    case Failure(exception) => Left(exception)
  }
}

这样,方法的调用者可以决定做什么。例如,您可以对此方法的结果进行模式匹配,并在记录错误时将Left(exception)转换为None

val queryResult: Option[Boolean] = exampleMethod("bad_query") match {
  case Right(result) => Some(result)
  case Left(exception) => {
    Logger.warn(s"There was an issue with exampleMethod: ${exception.getMessage}", exception)
    None
  }
}

答案 2 :(得分:2)

答案 3 :(得分:1)

这是Try类型

的好例子
def exampleMethod (query: String): Try[Boolean] =
{  
  Try
  { 
     //If this throws an exception, it will be caught within the Try as a Failure
    // and can be handled later, otherwise the result is stored in a Success
     boolQueryResult.evaluate()
  }
}

Try可以包装可能失败的表达式。它将包含Success中的值,如果抛出异常,则Try将在Failure中包含该异常。然后,您可以使用mapflatmapforeach等方法对值进行操作。更好的方法是修改您的evaluate方法以返回Try或其他适当类型而不是抛出异常,但这并不总是可行。

return是不必要的,不建议在Scala中使用。方法中最后一个表达式的结果将自动返回

另一个选择是根本不使用BooleanBoolean的问题在于它只能在需要三个状态时保持两种状态。您可以创建一个具有三种状态的新ADT,而不是使用包装器。

sealed trait ExampleResult
case object TrueResult extends ExampleResult 
case object FalseResult extends ExampleResult 
case object QueryError extends ExampleResult 

因为Trait是密封的,所以只有同一文件中的类可以扩展特性ExampleResult,所以你知道它将永远是这三个选项之一。

然后您可以像这样编写代码

def exampleMethod (query: String): ExampleResult =
{  
  try
  { 
     //This will take the input query and return "true" or "false" 
     //depending on the state of the database

     if(boolQueryResult.evaluate()){
       return TrueResult
     } else {
       return FalseResult
     }
  }
  catch
  {
     case e: Throwable => logger.info(e.toString)
  }
  logger.info("Something is wrong! I want to return a boolean with nothing in it!")
  return QueryError
  }
相关问题