結論から言うと、言語仕様の違いによるうっかりミスでした。
同様の事象をググるのが難しかったので、一例として残しておきます。
発生した問題
Observable.just("太郎")
.flatMap { [weak self] fristName -> String? in
guard let self = self else { return }
self.getLastName(of: firstName)
}
.filter { $0 != nil }
.subscribe(onNext: { lastName in
print(lastName)
})
上記のようなコードをXCodeでビルドすると、Cannot convert return expression of type '()' to return type 'String'
というエラーが、このコードを含む箇所以外で大量に発生しました。
エラーとして掲示されている箇所は、共通して戻り値が定義されていない関数のようでした。
ビルドエラーが出ている箇所をエディターで開くと、何事もなくビルドの項目から何事もなく消えました。
しかし、再度ビルドすると、消えたはずのエラーが復活してしまいました。
該当のコードをコメントアウトすると、ビルドが成功するので、ビルドエラーの原因はこのコードであることは間違いなさそうでした。
エラーメッセージをググると構文エラーであるのは分かりましたが、同様の事象を見つけることはできませんでした。
原因
guard let self = self else { return }
を以下のように修正しました。
guard let self = self else { return nil }
Swiftでは戻り値の指定がない場合はVoid()
が返るのを失念していました。
普段はPythonを書くことが多く、 Pythonでは戻り値の指定がない場合はnil
に相当するNone
が返ることに慣れているのでなかなか気づけませんでした。
return
したらnil
が返るから、戻り値の型String?
に合致すると高を括っていました。
エラーメッセージに()
があるので冷静に考えれば、Void()
に関係することは気付けたかもしれません。
とはいえ、ビルドエラーの発生箇所をコンパイラには正しく示してほしいものです。
Swiftに日頃から慣れ親しんでいる人であれば、こんなエラーにあたふたすることはないのでしょう。
PythonだけでなくRubyなどの言語になれたエンジニアも同様なので、参考になれば幸いです。