I've encountered a strange problem which I'm struggling to understand. I have written some code that creates an observable from callable. It compiles fine, but as soon as I specify a scheduler for it it changes the return type and doesn't compile.
Here is the code without the subscribeOn (which compiles):
/**
* Gets all the room bookings for the specified day
*/
override fun getRoomBookingsForDay(date: Date): Observable<Collection<Model.RoomBooking>> =
Observable.fromCallable {
Realm.getDefaultInstance().use { realm ->
// Get all the bookings that begin and end within the specified date
val dbRoomBookings =
realm.where(DBRoomBooking::class.java)
.greaterThan("timeFromUtc", date)
.lessThan("timeToUtc", date)
.findAllSorted("timeFromUtc")
if (dbRoomBookings.isEmpty()) {
emptyList()
} else {
dbRoomBookings.asSequence().map { dbRoomBooking ->
makeRoomBookingModel(dbRoomBooking)
}.filterNotNull().toList()
}
}
}
And here is the code with subscribeOn (which doesn't compile):
/**
* Gets all the room bookings for the specified day
*/
override fun getRoomBookingsForDay(date: Date): Observable<Collection<Model.RoomBooking>> =
Observable.fromCallable {
Realm.getDefaultInstance().use { realm ->
// Get all the bookings that begin and end within the specified date
val dbRoomBookings =
realm.where(DBRoomBooking::class.java)
.greaterThan("timeFromUtc", date)
.lessThan("timeToUtc", date)
.findAllSorted("timeFromUtc")
if (dbRoomBookings.isEmpty()) {
emptyList()
} else {
dbRoomBookings.asSequence().map { dbRoomBooking ->
makeRoomBookingModel(dbRoomBooking)
}.filterNotNull().toList()
}
}
}.subscribeOn(AndroidRealmSchedulers.realmThread())
The compile time error message is:
Type mismatch.
Required: Observable<Collection<Model.RoomBooking>>
Found: Observable<List<Model.RoomBooking>!>!
Surely, specifying the scheduler shouldn't change the type that is being returned? Any ideas?
I think you have to define the co-variance with the return-type:
override fun getRoomBookingsForDay(date: Date): Observable<out Collection<Model.RoomBooking>>
Using the out T
is the same as ? extends T
in Java.
Alternatively you can make sure to only use the Collection
. In your first example the return-type of Observable.fromCallable()
is inferred by the return-type of the fun
while it is inferred by the return-type of the Callable
in the second example. So just declare it directly:
Observable.fromCallable<Collections<Model.RoomBooking>> { ... }