Scala-返回一个布尔值,该布尔值既不是真的也不是假的
我已经读过为什么不鼓励在Scala中使用“null”。但是我遇到了一个问题,我想返回一个“空”布尔值,在某些条件下它既不是真的也不是假的Scala-返回一个布尔值,该布尔值既不是真的也不是假的,scala,Scala,我已经读过为什么不鼓励在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
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,然后该值将以布尔形式返回。但是,如果出现错误,执行catch块,我想返回一个非true或false的布尔值,以表明输入字符串有错误。在该方法的当前版本中,布尔值被初始化为“false”,这并不理想,因为它指示evaluate()返回false,而不是执行catch块。是否有方法初始化此变量,使其在引发异常时不会返回“true”或“false”?您可以使用
选项
类:
@bipll是对的<代码>选项[Boolean]是Scala实现所需功能的方法。就是这样做的
def exampleMethod(query: String): Option[Boolean] =
try {
Some(boolQueryResult.evaluate())
} catch {
case e: Throwable => logger.info(e.toString)
None
}
对于
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将在失败中包含该异常。然后可以使用map
、flatmap
和foreach
等方法对值进行操作。更好的方法是修改evaluate方法以返回Try
或其他适当的类型,而不是抛出异常,但这并不总是可能的
return
是不必要的,在Scala中不推荐使用。方法中最后一个表达式的结果将自动返回
另一个选择是根本不使用布尔值。Boolean
的问题在于,它只能保持两种状态,而您需要三种状态。您可以创建一个具有三种状态的新ADT,而不是使用包装器
sealed trait ExampleResult
case object TrueResult extends ExampleResult
case object FalseResult extends ExampleResult
case object QueryError extends ExampleResult
因为Trait是密封的,所以只有同一文件中的类可以扩展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
}
尽管其他答案建议使用选项
(返回Some(true)
、Some(false)
、或None
),但如果返回None
,则会丢失错误消息。因此,我建议使用with
示例可能如下所示:
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
}
}
一个好的scala方法不应该在Try
中返回Try
异常
,就像对象
:你不知道如何处理它。如果你知道方法中会发生什么样的错误-使用或者。如果不是-只传播错误并在调用者代码中处理。这是相当固执己见和肯定的ainly并不是Scala社区普遍认同的观点。我喜欢很多这样的答案,但这是我最终使用的解决方案。我喜欢它的简单性,尽管我希望有一种方法可以在Scala中使用一个简单的布尔术语来实现这一点。我相信在Java中,您可以简单地设置布尔==null。Scala是一个强类型的l由于代码< > null <代码>不是布尔值,它不允许。许多人认为java的松散类型和常数空校验是一个缺陷。如果某些东西不存在,那么它就成为了通过代码> >选项[BooLea] < /C> >,>代码>选项[INT] < /C>,<代码>选项[String ]。
,等等。这样接收代码就不会忘记检查null,因为访问布尔值
与访问选项[Boolean]
不同。