¿Cómo manejar adecuadamente una perspectiva variable nula en kotlin?

Mi antiguo método de versión de Java se ve así:

@Override public void closeSimpleAlertDialog() { if (mAlertDialog != null && mAlertDialog.isShowing()) { mAlertDialog.dismiss(); } } 

Como puede ver, se verifica si el enlace de reference nulo a un dialog mAlertDialog y si no es nulo, el método de llamada de comprobación isShowing() , y solo entonces causó un método de close – dismiss() . Muy simple

Me enfrenté a un problema: ¿cómo sigue estando en "Kotlin-style" para realizar la misma operación?

Mi primera versión se ve aquí:

 if (mAlertDialog != null && mAlertDialog?.isShowing) { mAlertDialog?.dismiss() } 

El siguiente paso cambia mAlertDialog != null && mAlertDialog?.isShowing en mAlertDialog?.isShowing ?: false y la última versión se ve así:

 if (mAlertDialog?.isShowing ?: false) mAlertDialog?.dismiss() 

Pero no entiendo Por qué necesito "?" si la comprobación nula ya ocurrió antes (aquí: mAlertDialog?. )?

Debido a que otro hilo puede hacer que la propiedad sea nula después de la verificación nula, y antes de la llamada para descartar. No sucederá si usa una variable local o let .

Por cierto, si omites el signo de interrogación y pasas el cursor sobre el rojo ondulante, IntelliJ te dice

Smart Cast para Dialog es imposible, porque mAlertDialog es una propiedad mutable que podría haberse cambiado en este momento

La forma canónica (AFAIK) de hacer eso con Kotlin sería

 fun close() { mAlertDialog?.let { if (it.isShowing) { it.dismiss() } } } 
 mAlertDialog?.isShowing ?: false 

Esta línea proporciona un valor de reserva (falso) en caso de que el dialog o la propiedad sea nulo.

Lo que probablemente estés buscando es:

 alertDialog?.let { if (it.isShowing()) it.dismiss() } 

Donde "it" es la propiedad antes del signo de interrogación null-checked. Si alertDialog es nulo, no se llamará a let y ten en count que si lo llamas sin el signo de interrogación, ingresará incluso si es nulo.

Si usas ? entonces está permitiendo el valor nulo para las variables.

Ejemplo:

 var a: String = "abc" a = null // comstacktion error var b: String? = "abc" b = null // ok b?.length 

Esto devuelve b.length si b no es nulo, y null en caso contrario.