添加 subscribeOn() 正在改变 return 可观察类型
Adding subscribeOn() is changing return type of observable
我遇到了一个我很难理解的奇怪问题。我写了一些代码,从可调用对象创建一个可观察对象。它编译得很好,但是只要我为它指定一个调度程序,它就会更改 return 类型并且不会编译。
这里是没有 subscribeOn 的代码(编译):
/**
* 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 的代码(无法编译):
/**
* 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())
编译时错误信息为:
Type mismatch.
Required: Observable<Collection<Model.RoomBooking>>
Found: Observable<List<Model.RoomBooking>!>!
当然,指定调度程序不应更改正在 returned 的类型?有什么想法吗?
我认为您必须使用 return 类型定义协方差:
override fun getRoomBookingsForDay(date: Date): Observable<out Collection<Model.RoomBooking>>
使用 out T
与 Java 中的 ? extends T
相同。
或者您可以确保只使用 Collection
。在您的第一个示例中,Observable.fromCallable()
的 return 类型由 fun
的 return 类型推断,而 return 类型推断第二个例子中的Callable
。所以直接声明就可以了:
Observable.fromCallable<Collections<Model.RoomBooking>> { ... }
我遇到了一个我很难理解的奇怪问题。我写了一些代码,从可调用对象创建一个可观察对象。它编译得很好,但是只要我为它指定一个调度程序,它就会更改 return 类型并且不会编译。
这里是没有 subscribeOn 的代码(编译):
/**
* 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 的代码(无法编译):
/**
* 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())
编译时错误信息为:
Type mismatch.
Required: Observable<Collection<Model.RoomBooking>>
Found: Observable<List<Model.RoomBooking>!>!
当然,指定调度程序不应更改正在 returned 的类型?有什么想法吗?
我认为您必须使用 return 类型定义协方差:
override fun getRoomBookingsForDay(date: Date): Observable<out Collection<Model.RoomBooking>>
使用 out T
与 Java 中的 ? extends T
相同。
或者您可以确保只使用 Collection
。在您的第一个示例中,Observable.fromCallable()
的 return 类型由 fun
的 return 类型推断,而 return 类型推断第二个例子中的Callable
。所以直接声明就可以了:
Observable.fromCallable<Collections<Model.RoomBooking>> { ... }