2013-04-25 41 views
0

以下定義:在scala中,檢查非空值並直接應用方法?

class Test { 
    var activated: Boolean = false 
} 

def maybeTest(): Test = { 
    if(...) { 
    val res = new Test 
    if(...) res.activated = true 
    } else null 
} 

我有很多if結構,像這樣的:

val myobject = maybeTest() 
if(myobject != null && myobject.activated) { 
    // Do something that does not care about the object 
} 

我想凝那麼一點點。有一個很好的方法來定義/寫這樣的事情,以避免一個NullPointerException:

if(maybeTest() &&> (_.activated)) { 
    ... 
} 

什麼是Scala實現這一目標的最佳途徑?

+3

爲什麼不使用[scala.Option(http://www.scala-lang.org/api/current/index.html#scala.Option)? – 4lex1v 2013-04-25 09:14:23

+0

我喜歡scala選項,但我在Android上開發,所以我創建的對象越少越好。 – 2013-04-25 09:18:24

+0

在maybeTest()中激活的示例調用可能會拋出一個NPE,如果maybeTest()會導致Null,那麼您首先必須檢查您的maybeTest的結果,然後調用激活 – 4lex1v 2013-04-25 09:47:46

回答

0

發現隱含的類的最佳途徑,這妥善處理無效的情況下(雖然它可能不是最有效的方式)。

implicit class CheckNull[T](obj: T) { 
    def call(f: T => Unit): Unit = if(obj != null) f(obj) else() 
    def is(f: T => Boolean): Boolean = if(obj != null) f(obj) else false 
} 

所以,我可以寫一個類型安全的方法,甚至呼籲:

if(maybeTest() is (_.activated)) { 
    ... 
} 
myObjectMaybeNull call (_.pause()) 

注意周圍(_.activated)括號是必要的。

2

您可以選擇包裝等這樣的代碼:

class Test(num: Int) { 
    def someNum = num 
} 

val test: Test = null 
Option(test).map(t => t.someNum) 

在這個例子中,如果您的變量爲空,那麼你會得到無,否則只是一些(值)工作

更新

如果你不想使用選項,那麼你可以定義這樣的功能

class Test(num: Int) { 
    def give = num 
} 

def ifDefAndTrue[T, K](obj: T)(ifTrue: T => Boolean)(then: => K) { 
    if (obj != null && ifTrue(obj)) 
    then 
} 

你的情況,這是這樣的:

val test = new Test // assuming that activated is false 

ifDefAndTrue(test)(_.activate) { 
    println("results in unit") 
} 

但它包含的副作用,而不是功能

+0

您是否在使用選項時建議使用以下選項: if(Option(test).foldLeft(false){(a,b)=> a || b.activated}){ ... }? – 2013-04-25 09:35:15

+1

Option(foo).filter(_。activated).foreach {_ => ...} – 2013-04-25 13:23:24

+1

不要忘記HOF的每個參數,比如map,foreach,filter等等和'ifDefAndTrue'!)以及所有名稱參數(如「getOrElse」,「getOrElseUpdate」等)都需要在每個使用點生成一個單獨的類並實例化該類。因此,「Option」可能不會像人們初看時那樣(相對)不太經濟的新實例。 – 2013-04-25 17:18:43

1

如何

for {m <- Option(maybeTest()) 
    if m.activated 
    } 
    { 
     ... // do something with non-null, activated, m 
    } 
+0

這也適用。 – 2013-09-18 15:33:26

+0

是的。它被測試:)是否更好,如果是味道的問題... – 2013-09-18 15:43:07