2016-10-08 34 views
3

對於這段代碼,科特林迫使我來處理一個空檢查的情況,而在它沒有其他線路,儘管是同樣的情況:爲什麼我被迫使用!在空檢查的組合?

if (r1 == null && r2 == null) 
    throw IllegalArgumentException("All nulls!") 
else if (r1 == null) 
    return r2!!.reading // <----- I am forced to !! here 
else if (r2 == null) 
    return r1.reading // <----- The compiler does not complain in this line 

這是一個錯誤或功能?

+0

R1和R2丘壑行之有效? – IRus

+1

爲什麼通過消除過程檢查非空值而不是直接檢查非空值?例如'R2 .reading:??R1 .reading:??拋出IllegalArgumentException( 「!所有空值」)' – mfulton26

+0

@ mfulton26了'if'的問題表達並不詳盡,即不覆蓋的情況下當兩個'R1 '和'r2'不爲空。所以,雖然你的建議在某些情況下可能有用,但在這種情況下,它並不等同。 – Ilya

回答

7

的科特林編譯器不會做的方式邏輯推理你期望:「我已經檢查了R1 == NULL和r2 == NULL,所以現在如果我只檢查R1 == null,則必須認識到r2不爲空「。它沒有。你沒有在該分支中檢查r2,所以它沒有看到它不是空的。

在第二種情況下,情況比較簡單:if (r1 == null) { ... } else { ... }。不要緊,你在else裏面有另一張支票;編譯器會發現您位於if (x == null)檢查的else分支中,並瞭解該值不爲空。

有添加這種邏輯的open feature request,但是,它不是在科特林隊的近期路線圖。

+0

我明白了。我只會期待那些!在多線程環境中。 – PedroD

1

可以略微調整你if表達,所以它會使少檢查,並有智能施法應用於r2

if (r1 == null) { 
    if (r2 == null) throw IllegalArgumentException("All nulls!") 
    return r2.reading 
} else if (r2 == null) { 
    return r1.reading 
} 
2

恕我直言,如果某些應用邏輯是互斥的。我傾向於使用when {}來聲明性地表達全部條件,而不是使用if(...) else if(..) else來組成邏輯。

使用when{}指定由案件的全部條件的情況下可以幫助開發人員只專注於這對於調試和以後的變化更容易具體情況。

相比之下,if else條件迫使開發人員從上到下追蹤,以獲得對其他人閱讀起來相對困難並且難以指出無法訪問的代碼的整體邏輯。

我遇到了一些複雜的if else代碼,我要建一個真值表理解邏輯的整體的一部分。

回到問題。智能用的情況下:) when{}

實現1

val someReading = when { 
    r1 != null && r2 == null -> r1.reading 
    r1 == null && r2 != null -> r2.reading 
    else -> throw IllegalArgumentException("All nulls!") 
} 

實現2

val someReading = 
     r1?.reading 
     ?: r2?.reading 
     ?: throw IllegalArgumentException("All nulls!") 
+0

請注意,當「r1」和「r2」都不爲空時,第一個實現會拋出,否則不應該拋出。第二個也不等於問題中的代碼。 – Ilya

相關問題