ダブル=
またはトリプルを使用する必要があります=
か?
if(a === null) {
//do something
}
または
if(a == null) {
//do something
}
同様に「等しくない」の場合:
if(a !== null) {
//do something
}
または
if(a != null) {
//do something
}
回答:
構造的等価性a == b
は
a?.equals(b) ?: (b === null)
したがって、と比較するnull
と、構造的等価性a == null
は参照等価性に変換されますa === null
ます。
よるとドキュメント、あなたが使用できるように、あなたのコードを最適化するにはポイントがありませんa == null
とa != null
注意変数が変更可能なプロパティがある場合、あなたは内部のnull非許容型へのスマートキャスト、それをすることはできませんというif
文は、(理由は値は別のスレッドによって変更されている可能性があります)let
。代わりに、安全な呼び出し演算子を使用する必要があります。
安全な通話オペレーター ?.
a?.let {
// not null do something
println(it)
println("not null")
}
Elvisオペレーターと組み合わせて使用できます。
エルビスオペレーター?:
(尋問マークがエルビスの髪の毛のように見えるので、私は推測しています)
a ?: println("null")
そして、あなたがコードのブロックを実行したい場合
a ?: run {
println("null")
println("The King has left the building")
}
2つを組み合わせる
a?.let {
println("not null")
println("Wop-bop-a-loom-a-boom-bam-boom")
} ?: run {
println("null")
println("When things go null, don't go with them")
}
if
nullチェックに使用しないのですか?a?.let{} ?: run{}
まれな場合にのみ適切ですが、それ以外は慣用的ではありません
null
チェックにifを使用しないことを提案していなかったので、他の実行可能なオプションをリストしていました。run
何らかのパフォーマンスのペナルティがあるかどうかはわかりませんが。わかりやすくするために回答を更新します。
a
がの場合、スコープ全体で正しくバインドされるvar
というa?.let{} ?: run{}
保証を使用しlet
ます。場合a
でval
は、違いはありません。
val
letの使用は異なり、それは悪いことです。私はこの記事がそれを説明するのに非常に優れていると感じました-Kotlin:nullチェックにLETを使用しないでください。
安全なアクセス操作
val dialog : Dialog? = Dialog()
dialog?.dismiss() // if the dialog will be null,the dismiss call will be omitted
Let関数
user?.let {
//Work with non-null user
handleNonNullUser(user)
}
早期終了
fun handleUser(user : User?) {
user ?: return //exit the function if user is null
//Now the compiler knows user is non-null
}
不変の影
var user : User? = null
fun handleUser() {
val user = user ?: return //Return if null, otherwise create immutable shadow
//Work with a local, non-null variable named user
}
デフォルト値
fun getUserName(): String {
//If our nullable reference is not null, use it, otherwise use non-null value
return userName ?: "Anonymous"
}
varの代わりにvalを使用する
val
読み取り専用で、var
変更可能です。スレッドセーフであるため、できるだけ多くの読み取り専用プロパティを使用することをお勧めします。
lateinitを使用する
不変のプロパティを使用できない場合があります。たとえば、Androidで一部のプロパティがonCreate()
呼び出しで初期化されるときに発生します。これらの状況に対して、Kotlinにはと呼ばれる言語機能がありlateinit
ます。
private lateinit var mAdapter: RecyclerAdapter<Transaction>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mAdapter = RecyclerAdapter(R.layout.item_transaction)
}
fun updateTransactions() {
mAdapter.notifyDataSetChanged()
}
@Benito Bertoliへの追加、
組み合わせは実際にはif-elseとは異なります
"test" ?. let {
println ( "1. it=$it" )
} ?: let {
println ( "2. it is null!" )
}
結果は次のとおりです。
1. it=test
しかし:
"test" ?. let {
println ( "1. it=$it" )
null // finally returns null
} ?: let {
println ( "2. it is null!" )
}
結果は次のとおりです。
1. it=test
2. it is null!
また、最初にelvisを使用する場合:
null ?: let {
println ( "1. it is null!" )
} ?. let {
println ( "2. it=$it" )
}
結果は次のとおりです。
1. it is null!
2. it=kotlin.Unit
便利なメソッドをチェックしてください、それは役に立つかもしれません:
/**
* Performs [R] when [T] is not null. Block [R] will have context of [T]
*/
inline fun <T : Any, R> ifNotNull(input: T?, callback: (T) -> R): R? {
return input?.let(callback)
}
/**
* Checking if [T] is not `null` and if its function completes or satisfies to some condition.
*/
inline fun <T: Any> T?.isNotNullAndSatisfies(check: T.() -> Boolean?): Boolean{
return ifNotNull(this) { it.run(check) } ?: false
}
以下は、これらの関数の使用方法の例です。
var s: String? = null
// ...
if (s.isNotNullAndSatisfies{ isEmpty() }{
// do something
}