Open1
【Swift】unwrap済みのoptionalな値を利用する際、コンパイルエラーで再度unwrapを求められることがある
起きたこと
次のようなRxSwiftを利用したコードで Value of optional type "SomeType?" must be unwrapped to refer to member "someProperty" of wrapped base type "SomeType"
というコンパイルエラーが出ました。
FluxのStoreにあるBehaviorRelayの値を、flatMapでunwrapしてUI側で利用するサンプルコードです。
store.$someStoredProperty
.flatMap { Observable.from(optional: $0) }
.asDriver(onErrorDriveWith: .empty())
.drive(Binder(self) { target, someProperty in
target.doSomethingA(someProperty) // `Value of optional type "SomeStoredType?" must be unwrapped to refer to member "someProperty" of wrapped base type "SomeStoredType"`
target.doSomethingB()
}).disposed(by: bag)
driveの中で利用しているsomePropertyはすでにunwrapされた値なので、このエラーには違和感があります。
実はこれ、後述するコードに誤りがあるとなぜかunwrapされたsomePropertyを利用している箇所にこのエラーが出るようです。
このサンプルコードで誤りとなるのは target.doSomethingB()
の部分。
書き換えのタイミングで doSomethingB
の関数を削除してしまっており、正しく出てほしいエラーは次のように Cannot find "doSomething" in scope
となります。
target.doSomethingB() // `Cannot find "doSomethingB" in scope`
そのためこの問題は target.doSomethingB()
を削除すればunwrapを求めるエラーが解消されます。
再現した環境
- Xcode 15.0
- RxSwift 6.0.0
その他検証
unwrapした値を利用するコードで、スコープ内に関数の定義がない関数の呼び出しを行ってみました。
すると、正しいエラーが表示されました。
func doSomethingA(int: Int?) {}
func someLifeCycle() {
var hoge: Int?
if let hoge = hoge {
doSomethingA(int: hoge)
doSomethingB() // `Cannot find "doSomethingB" in scope`
}
}
その他考えられること
- RxSwiftのバージョンが古い。