如何在scala中的单个语句中检查null?

the*_*cer 43 null scala inline

在我的scala代码中:

QueueManager.add(getObject)
Run Code Online (Sandbox Code Playgroud)

where getObject是返回类型对象的方法QueueObject.

def getObject : QueuObject = {
    val response = //some response
    return response
}
Run Code Online (Sandbox Code Playgroud)

有没有办法在添加QueueObject的同时检查响应为null?我知道我可以这样做:

if (getObject != null)
    QueueManager.add(getObject)
Run Code Online (Sandbox Code Playgroud)

但我不希望增加一定程度的缩进.有内联运营商吗?

谢谢.

Jes*_*per 72

尽量避免null在Scala中使用.它实际上只存在与Java的互操作性.在Scala中,Option用于可能为空的东西.如果您正在调用可能返回的Java API方法,请立即null将其包装Option.

def getObject : Option[QueueObject] = {
  // Wrap the Java result in an Option (this will become a Some or a None)
  Option(someJavaObject.getResponse)
}
Run Code Online (Sandbox Code Playgroud)

注意:您不需要在Scala中val使用或使用显式 return语句; 结果将是块中最后一个表达式的值(事实上,因为只有一个语句,所以甚至不需要块).

def getObject : Option[QueueObject] = Option(someJavaObject.getResponse)
Run Code Online (Sandbox Code Playgroud)

再说一下别人已经显示(例如呼叫foreachOption,这可能是稍显混乱),你也可以调用map它(而忽略了地图操作的结果,如果你不需要它):

getObject map QueueManager.add
Run Code Online (Sandbox Code Playgroud)

这将做什么,如果OptionNone,并调用QueueManager.add如果它是一个Some.

我发现使用常规if比使用任何这些"技巧"更清晰和简单,只是为了避免缩进级别.你也可以把它写在一行:

if (getObject.isDefined) QueueManager.add(getObject.get)
Run Code Online (Sandbox Code Playgroud)

或者,如果你想处理null而不是使用Option:

if (getObject != null) QueueManager.add(getObject)
Run Code Online (Sandbox Code Playgroud)

编辑 - 本是对的,getObject如果有副作用,小心不要多次打电话; 最好像这样写:

val result = getObject
if (result.isDefined) QueueManager.add(result.get)
Run Code Online (Sandbox Code Playgroud)

要么:

val result = getObject
if (result != null) QueueManager.add(result)
Run Code Online (Sandbox Code Playgroud)


Ben*_*son 12

如果它返回,Option[QueueObject]你可以使用像这样的结构getObject.foreach { QueueManager.add }.你可以将它包装在内,Option(getObject).foreach ...因为Option[QueueObject](null)None.


Dan*_*ral 12

Option(getObject) foreach (QueueManager add)
Run Code Online (Sandbox Code Playgroud)

  • 很酷,我没有意识到你只能写`(QueueManager add)`而不是`(QueueManager add _)`. (2认同)

Jea*_*let 7

虽然我确信@Ben Jackson的asnwer Option(getObject).foreach是这样做的首选方式,但我喜欢使用AnyRefpimp来允许我写:

getObject ifNotNull ( QueueManager.add(_) )
Run Code Online (Sandbox Code Playgroud)

我发现它看起来更好.

并且,以更一般的方式,我有时会写

val returnVal = getObject ifNotNull { obj =>
  returnSomethingFrom(obj)
} otherwise {
  returnSomethingElse
}
Run Code Online (Sandbox Code Playgroud)

如果我正在处理的话,用ifSome替换ifNotNull Option.我发现它比首先包装一个选项然后进行模式匹配更清晰.

(有关实现,请参阅在Scala中实现ifTrue,ifFalse,ifSome,ifNone等,以避免if(...)和简单模式匹配以及Otherwise0/ Otherwise1classes.)

  • 好的,但是你为什么要制作自己版本的`if` /`else`(将`else`重命名为`否则`......).这是一个有趣的练习,但它并没有在实践中赢得任何东西,可能会让你的代码更容易让别人阅读. (2认同)