2011-04-21 24 views
27

以我Scala代码:如何在scala中的单个语句中检查null?

QueueManager.add(getObject) 

其中getObject是返回QueueObject类型的对象的方法。

def getObject : QueuObject = { 
    val response = //some response 
    return response 
} 

有没有一种方法可以检查响应为空,同时添加QueueObject?我知道我可以这样做:

但我不想添加缩进级别。有没有内联的操作员?

谢谢。

回答

57

尽量避免在Scala中使用null。这真的只是为了与Java的互操作性。在Scala中,使用Option表示可能为空的事物。如果您正在调用可能返回null的Java API方法,请立即将其包装在Option中。

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

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

def getObject : Option[QueueObject] = Option(someJavaObject.getResponse) 

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

getObject map QueueManager.add 

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

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

if (getObject.isDefined) QueueManager.add(getObject.get) 

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

if (getObject != null) QueueManager.add(getObject) 

编辑 - 本是正确的,要小心不要如果它有副作用,请多次呼叫getObject;更好写这样的:

val result = getObject 
if (result.isDefined) QueueManager.add(result.get) 

或:

val result = getObject 
if (result != null) QueueManager.add(result) 
10

如果它返回Option[QueueObject]您可以使用像getObject.foreach { QueueManager.add }这样的结构。您可以将其与Option(getObject).foreach ...直接对齐,因为Option[QueueObject](null)None

7

虽然我敢肯定,@Ben杰克逊与Option(getObject).foreach asnwer是这样做的最佳方式,我喜欢用一个AnyRef皮条客,让我写:

getObject ifNotNull (QueueManager.add(_)) 

我发现它读取更好。

而且,在一个更一般的方式,我有时候写

val returnVal = getObject ifNotNull { obj => 
    returnSomethingFrom(obj) 
} otherwise { 
    returnSomethingElse 
} 

...与ifSome更换ifNotNull如果我处理一个Option。我发现它比第一个包装一个选项更清晰,然后进行模式匹配。

(对于实现,请参阅Implementing ifTrue, ifFalse, ifSome, ifNone, etc. in Scala to avoid if(...) and simple pattern matchingOtherwise0/​​类。)

+2

好,但为什么你想使自己的'if' /'else'(重命名'else'到版本'otherwise' ...)。这是一个有趣的练习,但它在练习中并不会赢得任何东西,并可能会让您的代码更容易让其他人阅读。 – Jesper 2011-04-21 09:16:22

+0

@Jesper我一般同意 - 尽管我发现'getObject ifNotNull(QueueManager.add(_))'比'Option(getObject).foreach(QueueManager.add(_))'更容易混淆。 'foreach'尤其会让我觉得可能有几个对象正在被处理,我总是必须回头看看它是否是一个'Option'。如果'Option'可以为这些方法命名的别名会很好。 – 2011-04-21 10:23:58

+0

Philippe是的,我不喜欢'foreach'这个技巧,在'Option'上使用的确有点误导。最简单的就是用普通的'if'来写。 – Jesper 2011-04-21 22:09:31

9
Option(getObject) foreach (QueueManager add) 
+2

很酷,我没有意识到你可以只写'(QueueManager add)'而不是'(QueueManager add _)'。 – ebruchez 2011-04-21 16:29:51