Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala-返回一个布尔值,该布尔值既不是真的也不是假的_Scala - Fatal编程技术网

Scala-返回一个布尔值,该布尔值既不是真的也不是假的

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

我已经读过为什么不鼓励在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,然后该值将以布尔形式返回。但是,如果出现错误,执行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]
不同。