web-dev-qa-db-ja.com

Kotlinでnullチェックする最良の方法は?

ダブル=またはトリプル=を使用する必要がありますか?

if(a === null)  {
//do something
}

または

if(a == null)  {
//do something
}

同様に、「等しくない」の場合:

if(a !== null)  {
//do something
}

または

if(a != null)  {
//do something
}
56
pdeva

どちらのアプローチも同じバイトコードを生成するため、好きなものを選択できます。

35
Michael

構造的平等a == bは次のように変換されます

a?.equals(b) ?: (b === null)

したがって、nullと比較すると、構造的等式a == nullは参照等式a === nullに変換されます。

docs によれば、コードを最適化しても意味がないので、a == nulla != nullを使用できます


変数が可変プロパティである場合、内部のnull不可タイプにスマートキャストすることはできませんifステートメント(値は別のスレッドによって変更された可能性があるため)で、代わりにletで安全な呼び出し演算子を使用する必要があります。

安全な呼び出し演算子?.

a?.let {
   // not null do something
   println(it)
   println("not null")
}


エルビス演算子と組み合わせて使用​​できます。

エルビス演算子?:(尋問マークがエルビスの髪のように見えるので推測しています)

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")
}
89
Benito Bertoli

Nullを処理するKotlinの方法

セキュアアクセス操作

val dialog : Dialog? = Dialog()
dialog?.dismiss()  // if the dialog will be null,the dismiss call will be omitted

機能を許可

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を使用

不変のプロパティを使用できない場合があります。たとえば、onCreate()呼び出しで一部のプロパティが初期化されると、Androidで発生します。これらの状況に対して、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()
}
7
Levon Petrosyan

@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!

また、エルビスを最初に使用する場合:

null ?: let {
    println ( "1. it is null!" )
} ?. let {
    println ( "2. it=$it" )
}

結果は次のとおりです。

1. it is null!
2. it=kotlin.Unit
5
BingLi224

便利なメソッドをチェックしてください。役に立つかもしれません:

/**
 * 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
}
4
Vlad