Kotlin: No se pueden aplicar dos condicionales a la vez. Verificar con el estilo de function de "cuerpo de retorno".

Tengo una verificación de function simple como esta:

fun parseValidBluetoothBrickedId(controllerId: String?): Boolean{ if(controllerId != null){ if(controllerId.startsWith(BLUETOOTH_NAME_PREFIX) && controllerId.length > BLUETOOTH_NAME_PREFIX.length) return true } return false } 

Quiero convertirlo a un estilo simplier:

  fun parseValidBluetoothBrickedId(controllerId: String?) = controllerId?.length > BLUETOOTH_NAME_PREFIX.length && controllerId?.startsWith(BLUETOOTH_NAME_PREFIX) 

pero IDE (Android Studio 3.0 Beta7) me da un error, subraya el operador mayor que ('>'):

Las llamadas de operador corresponden a una llamada calificada por punto 'controllerId? .length.compareTo (BLUETOOTH_NAME_PREFIX.length) que no está permitida aquí

También subraya como un controller de línea de error Id.. Inicia con (BLUETOOTH_NAME_PREFIX) y dice:

Escriba desajuste. Requerido: Boolean, Found Boolean?

¿Cuál es el problema, realmente? Es simplemente un método simple, funciona bien con el primer bloque estilo if-else.

No puede invocar compareTo (use el < operador) en controllerId?.length , ya que su tipo es Int? , lo que significa que podría ser null , en cuyo caso no se puede comparar como un número.

Del mismo modo, la controllerId?.startsWith(BLUETOOTH_NAME_PREFIX) devuelve Boolean? (dado que devolverá null si controllerId es null ), que no se puede pasar al operador && , solo un Boolean real puede hacerlo.

La solución aquí es hacer la comprobación null que estaba haciendo en su método original, y deshacerse de las llamadas seguras confiando en los lanzamientos inteligentes que transfieren su controllerId a String :

 fun parseValidBluetoothBrickedId(controllerId: String?): Boolean = controllerId != null && controllerId.length > BLUETOOTH_NAME_PREFIX.length && controllerId.startsWith(BLUETOOTH_NAME_PREFIX) 

Su function transformada no tiene la comprobación null :

 fun parseValidBluetoothBrickedId(controllerId: String?) = controllerId != null && controllerId.length > "".length && controllerId.startsWith("") 

Como en su primer ejemplo, la verificación nula es necesaria para que el comstackdor sepa que controllerId no es null . Después del control, el comstackdor usa "transmisión inteligente" y las llamadas son seguras. Por lo tanto, no tienes que usar ?. notación después del cheque.

Cuando haces controllerId?.length , ¿estás recibiendo un Int? . No puede comparar Int con un Int? . Esa es la razón por la que obtienes el primer error.

¿Obtiene el otro error porque controllerId?.startsWith(BLUETOOTH_NAME_PREFIX) devuelve Boolean? . No puede usar el operador && en un parámetro que admite nulos. Requiere dos parameters de tipo Boolean .

Para resolver los problemas, primero debe verificar controllerId != null . Esto arrojará el controllerId inteligente Id al tipo de String no nulable. Me gusta esto:

 fun parseValidBluetoothBrickedId(controllerId: String?): Boolean = controllerId != null && controllerId.startsWith(BLUETOOTH_NAME_PREFIX) && controllerId.length > BLUETOOTH_NAME_PREFIX.length 
  • Error de compilation de la llamada insegura de Kotlin en un receptor nulo después de un control nulo
  • ¿Cómo puedo crear una instancia de un object usando valores de parameters de constructor pnetworkingeterminados en Kotlin?
  • ¿Cuándo debería usar let {} y cuando simplemente! = Null
  • ¿Por qué la llamada insegura .run () funciona bien en un valor nulo en Kotlin?
  • Lanzamiento inteligente a kotlin.String
  • Kotlin null-check error
  • ¿Hay alguna manera de crear una matriz no nula a partir de un range?
  • Las comprobaciones nulas no se insertan para el tipo reificado cuando param no es nulo
  • Afirmación no nula de Kotlin en nulo
  • Manera idiomática de manejar lists anulables o vacías en Kotlin
  • function kotlin devuelve nulo