1.2の主だった(おもしろい)変更点の紹介です。1.2で最も改善されたのはif文です。letでOptionalをunwrapできる機能が大きく向上し、複数のOptionalを同時にunwrapできるほか、unwrapされた値について条件を加えることができるようになりました。Boolが真でふたつのOptional<Int>がnilではなく、大小関係にも条件がある、という条件を表してみます。1.2では1つのifで表現できます。uselet定数は再代入できません。1.1ではそのために、宣言と同時に値を決める必要がありました。1.2ではその制限が少し緩和され、値が使われる前に確実に初期化されるなら、宣言の後で値が決まってもよいことになりました。1.2ではletにできます。ifに限らずswitchなども利用できますが、全ての条件で初期化されることが保証されている必要があります。SetCollectionTypeにArrayやDictionaryなどに加えてSetが追加されました。Setは集合を表し、Foundation.frameworkのNSSetに対応します。Setの導入に合わせて、Objective-CでNSSetを利用していたAPIをSwiftから利用する場合にはSwiftのSetを使うことになります。println(abc)}NSSetと違って内包する値の型を指定でき、またArrayリテラルで表現できます。1.2からclassにもstaticな関数やプロパティを持てるようになりました。funcはclassかつfinalという意味になります。letで宣言した定数は最初にアクセスされた時点で評価されるという特徴を持ちます。+0000"クラス変数はObjective-Cには存在せず代替的な手法で実現していましたが、Swiftでついに用意された文法と言えます。1.1でクロージャを使うときに、返り値としてVoidを要求するところに1行だけ、Voidではない値を返す式があると、コンパイルエラーになっていました。これはクロージャが1行だけの式を持つとき、その式の結果がクロージャ全体の返り値として取り扱われ、型がミスマッチだと判定される結果です。このために無意味なreturnを付け加えるなどして回避していました。1.2ではこのようなときにVoidではない値が返っても許容されるようになりました。これで意味上は不要なreturnを書く必要がなくなり、すっきりします。1.2ではzip関数が導入されました。ふたつのSequenceTypeの組み合わせを簡単に作ることができます。要素数が異なる場合には短い方に合わせられます。castingキャスト関連でも非互換な変更などがあります。Int危険な操作であるときの一貫性のため、ダウンキャストするときas!を使うことになりました。SomeProtocol).something())}@objcではない通常のprotocolにもキャスト関連の操作ができるようになっています。@noescape関数が引数としてクロージャを受け取るとき、クロージャの内部で利用される変数はキャプチャされ、それぞれ強参照された状態となります。このためにクロージャの外のオブジェクトのプロパティなどを利用する場合にはself.で修飾する必要があります。これによってクロージャを実際に評価するタイミングはいつでもよいことになっています。クロージャを受け取ってすぐに評価することが決まっている関数の場合はどうでしょう。いうときはキャプチャする必要が無いし、self.も不要です。キャプチャしない方がパフォーマンス上でも有利でしょうし、最適化しやすいかもしれません。このようにすぐに評価されることがわかっているクロージャのために追加された新しいアノテーションが@noescapeです。U?Optionalのmapでは上記のように@noescapeされています。このためクロージャで使う変数がプロパティであってもself.は不要です。このようにSwiftではこれらの挙動をescapeという言葉で表しています。[U]ところでArrayのmapを見てみると、上記のように@noescapeアノテーションがないことが分かります。一貫性がないように思われるかもしれませんが、これには理由があるように思えます。lazy()関数などを用いて遅延評価する場合にはescapeせざるを得ません。これは簡単な実験で確かめられます。}println(NSDate().timeIntervalSinceDate(start))このようにlazy()関数を使えばmap中でsleep(1)していても一瞬で実行が終わり、result[2]などresultの要素にアクセスしたとき初めてmapのクロージャが評価されます。このlazy()を消すと、このスニペットは少なくとも3秒の実行時間を必要とします。これがArray.mapがescapeを必要とする理由です。この@noescapeが追加されたのに合わせてデフォルトでは@autoclosureもescapeされなくなりました。escapeしてほしい場合には@autoclosure(escaping)と書く必要があります。flatMap新しいflatMap関数を使うとmapではできないちょっとしたことが簡単にできるようになります。F]上記の例のように、Arrayの要素に何らかの変換を行うとき、flatMapなら要素毎に新たなArrayを返しても2次のArrayになりません。Optional(1)また上記の例では、OptionalのmapとflatMapの違いを示しています。mapの中でさらにOptionalな値を返すとOptional<Optional<Int>>を得ることになります。flatMapではOptional<Int>です。これは非常に有用であることがわかるでしょう。このようにflatMapはmapとよく似ていますが、最初のArrayと要素数が変わったArrayが返ったり、多重のOptionalを避けられたりといった特徴があります。[45]上記はこれの応用例で、ふつうのmapであればArray<Int?>が返るところを、nilを除去してArray<Int>にしています。1.2ではFoundation.frameworkにも少し拡張が増えています。println(path)}enumeratorAtPathはNSDirectoryEnumeratorというNSEnumeratorのサブクラスを返します。inが使えませんでした。inできるようになりました。Swiftはこのように、Foundation.frameworkについてSwiftから利用しやすいように多少の拡張を加えており、今後もこれらが拡充されていく可能性があります。String/Array/DictionaryNSStringなどのFoundation.frameworkのオブジェクトから対応するSwiftのStringなどへの暗黙的な変換が行われなくなりました。Stringなどと書いてキャストしておく必要があります。逆のStringからNSStringといった変換はこれまで通り暗黙的に行われます。SwiftからObjective-Cのヘッダを見たときにはNSStringはStringになっており、Swiftからはほとんど常にStringを利用していることになるので、実際的にこれが問題になるケースは少ないでしょう。CoreFoundation.frameworkに関するオブジェクトを利用するときは別です。count要素数を数える関数の名前が変わりました。1.2と共に様々なパフォーマンスが改善されました。Swiftで書かれたプログラムのパフォーマンスが改善されたほかにも興味深い変更があります。buildSwiftのコンパイルがインクリメンタルになりました。これまでは、ひとつのファイルを変更したときにも全てのファイルのコンパイルをやり直す必要がありましたが、これからは必要最低限のファイルをコンパイルし直すだけでよくなりました。今後も、変更したファイルだけをコンパイルし直すのではなく、変更が影響するであろうファイル全てをコンパイルし直す必要があります。6.3.1の問題かもしれません。Optimizationオブジェクト指向のパラダイムにおいて、クラスを継承してメソッドをオーバーライドするというのがあります。メソッドを呼び出す際にはオーバーライドされた後の実装を呼び出す必要があるということです。プログラムの実行中、メソッドの呼び出しやプロパティを操作する時に、実際に呼び出すべき対象を動的に解決します。dicpatchと呼んでいます。ここで、例えばfinal修飾されているメソッドは、ぜったいにオーバーライドできません。dispatchする必要がないので、Swiftのコンパイラは静的に解決してくれます。dispatchが行われない分、実行時のパフォーマンスは改善します。アクセス制御のprivateで修飾されていれば、そのファイルの外からはオーバーライドできません。dispatchをしないようにコンパイルできます。private修飾はパフォーマンスにも役立っていることがわかります。Optimizationです。internalで修飾されていればそのモジュールの外からオーバーライドされません。dispatchを避けることができます。この最適化は比較的時間がかかるため、現在のところオプションになっています。これらの話題はSwiftのブログにも書かれています。1.2に合わせてObjective-Cにも変更があります。変数や引数、返り値などがnilを取り得るかをアノテートできるようになりました。nullableやnonnullで修飾することでこれが可能です。全てにこれらのアノテーションを付けて回るのは現実的ではないので、NS_ASSUME_NONNULL_BEGINとNS_ASSUME_NONNULL_ENDで囲われている部分はnonnullということになっています。基本的にはこれで囲んでおいて、nullableだけ明示的に書くのがよいでしょう。OptionalではなくOptionalかそうでないかはっきりします。Objective-Cにおいても、nonnullとアノテートされたポインタにnilを入れようとしていれば静的解析で検出されます。実行時には影響しません。Swiftはまだ変わり続ける生きた言語です。1.2はSwiftの正式なリリース以来もっとも大きな変化で、開発者にとっても非常に歓迎すべき改善が数多くあります。1.2でバリバリ開発していきたいですね。見るいっしょにSwiftでバリバリ開発しませんか。1.2Tweet関連記事2016-12-27年末年始に飲み過ぎないために諸君は酒が好きだろうか。2.2寒さも和らぎ、日によっては春の訪れを感じさせる今日この頃、...2016-01-01Swiftにおけるclassとstructの使い分け新年あけましておめでとうございます。検索リンクはてなブログブログをはじめる(無料)お知らせ最新記事SwiftUIではSingletonの代わりにEnvironmentを使うことができる紛らわしい文字列をもっと紛らわしくするapple/swift-formatを試す息子にカメラを与えるCoreImage.CIFilterBuiltins月別アーカイブはてなブログをはじめよう!cockscombさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。