Cuál es el enfoque correcto cuando la function de Kotlin no toma el tipo de nullable

Así que estaba resolviendo el problema de Koans y, a través de mi solución demasiado compleja, tropecé con algo que me molesta. Estaba usando la function Int.compareTo () en types anulables. Es "fácil" si el primero es anulable porque solo escribo:

val a : Int? = 1 val b : Int = 1 a?.compareTo(b) 

Pero si b es nulable, entonces no pude hacer que funcione, ¿quizás me perdí algo en alguna parte? Entonces, ¿qué hacer cuando este es el caso?

 val a : Int? = 1 val b : Int? = 2 a?.compareTo(b) 

Aparece un error de syntax que dice "No se puede invocar ninguna de las siguientes funciones con los arguments suministrados".

Pero, cuando presento esto:

 val a : Int? = 1 val b : Int? = 2 val x : Int = b ?: 0; o1?.compareTo(x) 

Funciona, pero parece que no es la forma correcta de hacerlo. ¿Hay una mejor manera?

Tu puedes hacer

 val a: Int? = 1 val b: Int? = 2 b?.let { a?.compareTo(b) } 

let block se ejecutará solo si b no es nulo.

O solo

 if (a != null && b != null) { a.compareTo(b) } 

Creo que la segunda solución es muy clara y fácil de leer.

La firma del método Int.compareTo () no está definida para arguments anulables, por lo que no es posible hacerlo sin garantizar la security nula del argumento, por ejemplo, usando un operador elvis tal como lo ha sugerido.

Debería intentar implementar su solución sin anulabilidad. Pero si aún lo necesita y si es seguro suponer que null==0 no debería usar el ?. llamada de método Te devolverá un Int? también. Simplemente asigna ambos integers null a 0.

 (a?:0).compareTo(b?:0) 

La única mejor manera es implementar compareTo yourself. La comparación pnetworkingeterminada no sabe qué resultado desea cuando compara, por ejemplo, 12 con null o null con null . Solo sabe cómo comparar numbers reales. Creo que tu mejor manera es implementar el comportamiento que deseas para tratar con null s.

Ejemplo de implementación:

 fun main(args: Array<String>) { println(compareNullableInts(null, 2)) // -1 println(compareNullableInts(null, null)) // 0 println(compareNullableInts(2, null)) // 1 println(compareNullableInts(10, 5)) // 1 } fun compareNullableInts(a: Int?, b: Int?): Int { if (a == null && b == null) return 0 if (a == null) return -1 if (b == null) return 1 return a.compareTo(b) } 

la expresión debería ser así:

 val result = b?.let { a?.compareTo(b) ?: -1 } ?: 1; 

Ejemplos

 > a = 1 b = 2 ---> -1 > a = null b = 2 ---> -1 > a = null b = -1 ---> -1 > a = 1 b = null ---> 1 > a = -1 b = null ---> 1 > a = null b = null ---> 1 // the order is no matter 

SI quieres que null compare null return 0 entonces la expresión es un poco larga:

 val result = b?.let { a?.compareTo(b) ?: -1 } ?: a?.let { 1 } ?: 0; 

Nota : no le importa el performance, ya que let function es una function en línea. lo que significa que generará el código como el siguiente en java:

 int result = b != null ? a != null ? a.compareTo(b) : -1 : a != null ? 1 : 0; 
  • Cómo crear una list con un argumento genérico en Kotlin
  • RxJava manejando múltiples devoluciones de llamada dentro de un observable
  • ¿Cuál es la diferencia entre dos conversiones de Long a ByteArray?
  • ¿Cómo puedo ejecutar files Kotlin-Script (.kts) desde Kotlin / Java?
  • En Kotlin, ¿cómo abro un enlace en una nueva window?
  • ¿Puede JRebel volver a cargar las classs de Kotlin cuando son utilizadas por el plugin kotlin-maven-plugin en maven?
  • Solo la primera testing pasa con TestScheduler cuando se ejecutan varias testings (Kotlin)
  • El color de background de la image del elemento de Android ListView no cambia
  • ¿Por qué ocultar un Fragmento causa una exception de puntero nulo?
  • Disruptor LMAX con Kotlin: ¿No se puede usar lambda?
  • Cómo acceder al valor de campo en el método de propiedad get ()