Kotlin RxJava Bug Nullable

Me encontré con un problema en mi aplicación de Android usando Kotlin y RxJava. Se presenta a continuación.

import rx.Observable data class TestUser(val name: String) fun getTestUser(): Observable<TestUser> { return Observable.just(TestUser("Brian")).flatMap { getUser() } // this compiles } fun getTestUser2(): Observable<TestUser> { val observable = Observable.just(TestUser("Brian")).flatMap { getUser() } return observable // this does not compile } fun getUser(): Observable<TestUser?> { return Observable.just(null) } 

En getTestUser2 , el comstackdor infiere el tipo de devolución final como Observable<TestUser?> Y no comstack. Sin embargo, en getTestUser el código se comstack y, cuando se ejecuta, cualquier suscriptor de ese observable puede recibir una sorpresa cuando TestUser devuelve el null .

Supongo que tiene que ver con ir y venir entre Kotlin y Java. Pero, el hecho de que el comstackdor pueda ver la diferencia en getTestUser2 me hace pensar que esto podría ser reparable.

Editar

Esto está en Kotlin 1.0, la versión final lanzada ayer (15 de febrero de 2016).

La firma de la function flatMap es la siguiente cuando se usa en Kotlin:

 public final fun <R: Any!, T: Any!> Observable<T>.flatMap( func: ((T) -> Observable<out R!>!)! ) : Observable<R!>! 

De los documentos:

Cualquier reference en Java puede ser null , lo que hace que los requisitos de Kotlin de security nula estricta no sean prácticos para los objects provenientes de Java. Los types de declaraciones Java se tratan especialmente en Kotlin y types de plataforma llamados. Las comprobaciones nulas se relajan para dichos types, por lo que las garantías de security para ellos son las mismas que en Java

y

T! significa " T o T? "

Esto significa que el comstackdor de Kotlin puede considerar el tipo de retorno de la function flatMap como Observable<TestUser> u Observable<TestUser?> , o incluso Observable<TestUser>? . La parte de relajación dice "no queremos molestarte con estos types desconocidos, probablemente lo sepas mejor".

Dado que el tipo de devolución se proporciona explícitamente en getTestUser() , usa el primero. Dado que el tipo de observable no se da explícitamente, lo infiere a Observable<TestUser?> , Basado en la function getUser() .


Como @voddan comentó, hay un problema abierto al discutir este problema: https://youtrack.jetbrains.com/issue/KT-11108

  • RxJava2 cómo separar diferentes implementaciones de emisor observable
  • Convirtiendo un Observable en un Flujo con contrapresión en RxJava2
  • RxJava: onBackpressureBlock () comportamiento extraño
  • Convierte el código de RxJava a Kotlin correctamente
  • Fusionar datos de diferentes Observables y elegir diferentes estrategias de búsqueda, según la disponibilidad de datos
  • Reemplazar callbacks llamados externamente con RxJava
  • RxJava, ¿Qué pasó si no llamo a disponer?
  • RxJava2 observable no procesando en Siguiente cuando hay un cambio
  • Modelo lleno con respuesta extra usando Rx
  • RX java / Android cómo lograr este brindis en cada clic usando el operador de rebote
  • RxKotlin: tratando de agregar errores personalizados capturando