Tenemos que cubrir todas las twigs con todas las expresiones Control-Flow en Kotlin?

Miré los documentos del website de Kotlin, solo hay dos expresiones Control-Flow: if y when .

Por if :

la expresión es necesaria para tener una twig else

Para when :

La twig else se evalúa si no se cumple ninguna de las otras condiciones de twig. Si when se usa como una expresión, la twig else es obligatoria, a less que el comstackdor pueda probar que todos los casos posibles están cubiertos con condiciones de twig.

Pregunta

Entonces parece que no hay forma de hacer una expresión de Control-Flow sin cubrir todas las twigs, ¿Es correcto? Si no, ¿hay alguna manera de hacer que una expresión de Control-Flow pierda algunas twigs? Si es así, ¿por qué?


El siguiente código ocurrirá if must have both main and 'else' branches if used as an expression

 override fun onReceive(context: Context?, intent: Intent?) { intent?.let { if (it.action == MySDK.BROADCAST_ACTION_LOGIN) { mListener.get()?.loggedOn(LoggedOnUserInfo.IT) }else if (it.action == MySDK.BROADCAST_ACTION_LOGOUT) { // Occur 'if must have both main and 'else' branches if used as an expression' mListener.get()?.loggedOut(LoggedOutUserInfo()) } } } 

Pero después de la compilation de pase de código …..

 override fun onReceive(context: Context?, intent: Intent?) { intent?.let { if (it.action == MySDK.BROADCAST_ACTION_LOGIN) { mListener.get()?.loggedOn(LoggedOnUserInfo.IT) context!!.unregisterReceiver(this) // only add this line to test. }else if (it.action == MySDK.BROADCAST_ACTION_LOGOUT) { mListener.get()?.loggedOut(LoggedOutUserInfo()) } } } 

El truco aquí es no usar el if como expresión. Mi suposition es que colocaste el bloque if let , que devuelve su última statement, usando así el "resultado" de if , y así lo trata como una expresión.

Sugiero descartar la function de let (de todos modos, es inútil):

 override fun onReceive(context: Context?, intent: Intent?) { if(intent != null) { if (intent.action == MySDK.BROADCAST_ACTION_LOGIN) { mListener.get()?.loggedOn(LoggedOnUserInfo.IT) } else if (intent.action == MySDK.BROADCAST_ACTION_LOGOUT) { mListener.get()?.loggedOut(LoggedOutUserInfo()) } } } 

Su segunda versión se comstack porque context!!.unregisterReceiver(this) tiene un tipo diferente que mListener.get()?.loggedOut(LoggedOutUserInfo()) , lo que hace que los types no coincidan y previene el uso de if como una expresión.

PD

Kotlin tiene bastantes estructuras de control potentes. Yo personalmente prefiero esta versión:

 override fun onReceive(context: Context?, intent: Intent?) { intent ?: return when(intent.action) { MySDK.BROADCAST_ACTION_LOGIN -> mListener.get()?.loggedOn(LoggedOnUserInfo.IT) MySDK.BROADCAST_ACTION_LOGOUT -> mListener.get()?.loggedOut(LoggedOutUserInfo()) } } 

Entonces parece que no hay forma de hacer una expresión de Control-Flow sin cubrir todas las twigs, ¿Es correcto?

En el segundo caso

 mListener.get()?.loggedOn(LoggedOnUserInfo.IT) context!!.unregisterReceiver(this) 

Ya no es una expresión, todo el bloque if es una statement. Sin embargo, también puede proporcionar algo else con la Unit en un primer caso si realmente necesita una expresión:

 if (it.action == MySDK.BROADCAST_ACTION_LOGIN) { mListener.get()?.loggedOn(LoggedOnUserInfo.IT) } else if (it.action == MySDK.BROADCAST_ACTION_LOGOUT) { // Occur 'if must have both main and 'else' branches if used as an expression' mListener.get()?.loggedOut(LoggedOutUserInfo()) } else Unit 

Pero sería mejor evitar este código porque es less legible.

  • Al pasar una matriz de Parcelable con Intent.putExtra
  • Interoperabilidad de Kotlin-JS: uso de construcciones de lenguaje
  • ¿Se puede implementar Applicative "muy bien" en kotlin?
  • ¿Cómo puedo llamar a collect (Collectors.toList ()) en un Java 8 Stream en Kotlin?
  • Kotlin: cómo el parámetro pnetworkingeterminado en "fun main (parameters: Array <String>)" imprime "guest" sin asignar ningún valor
  • Cómo detener el service de notificación en Android Oreo
  • ¿Hay alguna manera de build un HashSet con function de initialization en Kotlin?
  • ¿Por qué no veo nada útil en Logcat al llamar al método de Kotlin?
  • Cómo agregar un nuevo set de orígenes con gradle kotlin-dsl
  • Kotlin: Lista modificable (inmutable) a través del reparto, ¿es legítimo?
  • Intellij no incluye la dependencia de gradle en classpath al ejecutar una aplicación