読者です 読者をやめる 読者になる 読者になる

try! Swift Swiftのエラー処理についての三つの話 #tryswiftconf Day1-6

try! Swift 2016

(十分に書き取れていない!申し訳ない!!)

twitter.com

エラー処理は安全なコードを書く上で重要です。私のプレゼンテーションでは、主に私の経験と考えに基いて、また Error Handling Rationale and Proposalswift-evolution のメーリングリストでの議論にも触れながら、 Swift におけるエラー処理の論点を整理します。

f:id:niwatako:20160302143023j:plain

私にとって初めてのプレゼンです。

エラーハンドリングについて3つの話をします。

オプショナルと出会う

Swiftに出会う前にオプショナルのようなものに触れています。Basicで。

C言語のエラー処理では忘れてしまいがち

f:id:niwatako:20160302145656j:plain

Javaプログラマに無理矢理書かせて良い仕組みだと思った

f:id:niwatako:20160302145712j:plain f:id:niwatako:20160302145729j:plain

エラーを無視したい時もある。そういう時にも意味のないエラーハンドラーを書く必要があります。 f:id:niwatako:20160302143254j:plain

それからSwiftのOptionalに出会いました。NullPointerを避けます。

f:id:niwatako:20160302145834j:plain オプショナルによってもっと一般化出来ます。遅延評価が可能でオプショナルを変数に代入してから使うことが出来ます。 f:id:niwatako:20160302145844j:plain

ただそれほどバラ色ではありません。2乗したりすると入れ子になっていきます。

Json変換でも、デコード途中でFailすることがあります。 こういったものをどうやってイニシャライズするか。 flatmapはネストが深くなるので

f:id:niwatako:20160302145926j:plain

アプリカティブスタイルでは使いやすいです。でも増えたら大変ですね。

糖衣構文でも使いやすくなっている。OptionalChainingもつかえる。

f:id:niwatako:20160302143704j:plain

OptionalはTypeSafeでありながら実用的です。

Success or Failure

f:id:niwatako:20160302143755j:plain

デバッグがしづらい。パースでどちらがFailしたのかわかりづらい f:id:niwatako:20160302143826j:plain

3つの解決策を考えました。

Touple f:id:niwatako:20160302143854j:plain

4種類で最後の2つが好ましくない

f:id:niwatako:20160302143916j:plain

f:id:niwatako:20160302143927j:plain

f:id:niwatako:20160302143940j:plain

Unionで拡張するのはSwiftらしくない

f:id:niwatako:20160302144002j:plain f:id:niwatako:20160302144012j:plain f:id:niwatako:20160302144017j:plain

ResultがOptionalのような糖衣構文があれば便利 f:id:niwatako:20160302144039j:plain

しかしうまく行かない例 f:id:niwatako:20160302144053j:plain

増えると困る

f:id:niwatako:20160302144138j:plain

このように宣言すると f:id:niwatako:20160302144155j:plain

幾つかの例外だけ処理できればよいのではないか。

f:id:niwatako:20160302144230j:plain

オペレーションをケースによって分岐させたいがすべてのエラーを対処したくない。

f:id:niwatako:20160302144301j:plain

Try

Swift2.0においてtry catchが導入されました。 最初の印象は悪かったですが勉強したらいいものだと分かりました。

何故トライキャッチを入れたかはドキュメントに書いてあります。

f:id:niwatako:20160302144442j:plain

Manuao propagation と Automatic propagation すべてのプログラマがこれらを理解するのは難しいかと思います。

コアチームはHaskellのDoに触れています f:id:niwatako:20160302144537j:plain

Automatic Propagation をSwiftに導入することはいいことです。

一見安全でないかのようですが安全 f:id:niwatako:20160302144613j:plain

f:id:niwatako:20160302144634j:plain Javaは何のエラーが飛んで来るかわからない。

Swiftでも同じことが起きるのではないかと思った。 f:id:niwatako:20160302144711j:plain

しかしSwiftではtryを書きます。どの行からエラーが出るか明確になります。 f:id:niwatako:20160302144748j:plain

Untype Throw がなくなりました。

f:id:niwatako:20160302144809j:plain

Marked Propagationはこれらを解決します f:id:niwatako:20160302144839j:plain

じゃあこれをOptionalに導入したら?

CoreTeamによればOptionalはシンプルなエラーを表す。

f:id:niwatako:20160302144927j:plain

私はこう使えばいいと思っている。

f:id:niwatako:20160302144942j:plain

これをResultに応用することも出来る。 f:id:niwatako:20160302144958j:plain

Resultでより柔軟なエラーハンドリング、遅延処理が可能になる。

具体例を上げます。

f:id:niwatako:20160302145026j:plain f:id:niwatako:20160302145045j:plain

MapとThrow、このような形で書けます。 f:id:niwatako:20160302145103j:plain

f:id:niwatako:20160302145118j:plain

Resultとしてthrowを使うとCompilation Errorが出る。 でもトータルで考えるとResultをThrowで使ったほうがいいと思っている

f:id:niwatako:20160302145218j:plain

Promiseを実装してみた f:id:niwatako:20160302145231j:plain

f:id:niwatako:20160302145255j:plain

SwiftでもAsync、 waitをSwiftで扱うことを議論する必要があると私は思います。このシンタックスSwiftで使うと下のようになります。

f:id:niwatako:20160302145333j:plain async await throw result それぞれが共通のコンセプトを持っています。

f:id:niwatako:20160302145439j:plain f:id:niwatako:20160302145448j:plain

私の考えを話してきました。みなさんのSwiftのエラーハンドリングの考えを聞きたいです。

これから無料のオンラインの書籍を出していきたいと思っています。 安全ではない、複雑な環境に対する苦労がある f:id:niwatako:20160302145555j:plain

Swiftオープンソースになったので、これを私たちの中でも実践できると思っています

f:id:niwatako:20160302145621j:plain

気に入った記事は はてなブックマーク

はてなブックマークアプリiOS開発チームから来ました! はてなブックマークにはSwift特集があります! 良い記事を見逃さないように、ご利用ください! http://b.hatena.ne.jp/hotentry/it/Swift

そして良いまとめ記事があったらはてなブックマークでブックマークしましょう! try! Swift の記事で盛り上がると嬉しいです!