[kotlin] Kotlin에서 null 검사를하는 가장 좋은 방법은 무엇입니까?

double =또는 triple을 사용해야 =합니까?

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 == nulla != null

참고 변수가 변경 가능한 속성이있는 경우, 당신은 내부의 비 nullable 형식에 스마트 캐스트를 할 수 없다는 if문 (때문에 값이 다른 스레드에 의해 수정되었을 수 있습니다.)와 함께 안전한 호출 연산자를 사용해야합니다.let 대신 .

안전한 통화 교환 원 ?.

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

Elvis 연산자와 함께 사용할 수 있습니다.

Elvis 연산자 ?: (심문 표시가 Elvis의 머리카락처럼 보이기 때문에 추측합니다)

a ?: println("null")

그리고 코드 블록을 실행하려면

a ?: run {
    println("null")
    println("The King has left the building")
}

두 가지를 결합

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")
}


답변

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()
}


답변

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


답변