2
votes

I'm confused about behavior of subscribe method in RxSwift.
This is sample code.

let observer1 = PublishSubject<String>()
let observer2 = PublishSubject<String?>()

let observable1 = Observable.just("")
let observable2 = observable1.map { $0 }

_ = observable1.subscribe(observer1) // #1. OK
_ = observable1.subscribe(observer2) // #2. Error
_ = observable2.subscribe(observer2) // #3. Error
_ = observable1.map{ $0 }.subscribe(observer2) // #4. OK

I understand that #2 and #3 get an error.
Because the observer is a nullable-string type, it is strictly different from the type that the observable holds.

But I can not understand #4.
If directly subscribe of the mapped observable, it did not get an error.
As shown in #3, the return value of the mapped observable1 was Observable.

I look forward to reply.

1

1 Answers

1
votes

This is because .map { $0 } actually returns a Observable<String?> in the fourth case!

Ww can cast the return value to a Observable<String>:

_ = (observable1.map{ $0 } as Observable<String>).subscribe(observer2)

It stops working! This implies that the value returned by map without the cast must be different. And there's only one possibility - Observable<String?>. $0 can't be implicitly convertible to other types.

The compiler sees that you are calling subscribe(Observable<String?>) and infers the return type of map to be Observable<String?> because only then can subscribe be called successfully.

But if you don't give the compiler enough context to figure out the type that map should return, like you did in the let observable2 = ... line, then the compiler thinks you want a Observable<String>.

Basically, the compiler is being smart.