layout | title | next_item | ||||
---|---|---|---|---|---|---|
page |
おわりに |
|
本書では、 Swift の根幹である Value Semantics と Protocol-oriented Programming に焦点を当て、 Swift とはどのような言語なのかを説明してきました。そのことを、 "はじめに" では
Swift の Heart (中心)となる概念を説明することを通して、 Swift の Heart (心)の形を描き出す
と表現しました。本書を通して描いてきた Heart の形は次のようになります。
この図の根底にある、原点とも言えるものが Value Semantics と 値型 です。
- [第 1 章 {{ site.data.book.chapters[0].name }}]({{ site.data.book.chapters[0].path }})
本書で最初に取り上げた、すべての大元にあったものが Value Semantics でした。本書のすべての話は、 Value Semantics が大切だということを前提に、 Swift ではどのようにして Value Semantics 中心のコードが実現されているかという話だと言えます。
そのため、まず初めに Value Semantics とは何かを、次に、 Value Semantics を持たない型が引き起こす問題について説明しました。
- [{{ site.data.book.chapters[0].sections[0].name }}]({{ site.data.book.chapters[0].sections[0].path }})
- [{{ site.data.book.chapters[0].sections[1].name }}]({{ site.data.book.chapters[0].sections[1].path }})
ミュータブルクラス ( ミュータブル な 参照型 )は Value Semantics を持たないので、多くの言語では イミュータブルクラス ( イミュータブル な 参照型 )を使って Value Semantics が実現されています。しかし、 Swift はその代わりに 値型 を使って Value Semantics を実現します。 値型 を使えば、 イミュータブルクラス と比較して、状態変更を伴うコードを簡潔に記述することができます。
値型 は、 ミュータブルクラス の持つ状態変更の簡潔さと、 イミュータブルクラス の持つ Value Semantics の利点の双方を兼ね備えたものと考えられます。そのような 値型 を使って Value Semantics を実現する、それが本書で説明してきた話の原点でした。
- [{{ site.data.book.chapters[0].sections[1].name }}]({{ site.data.book.chapters[0].sections[1].path }})
Heart の図には、 Value Semantics と 値型 を原点として、二つの軸が描かれています。その一つが、左方向に伸びる 「値型中心の世界を実現」 する軸です。
値型 を使うことで ミュータブルクラス と イミュータブルクラス のいいとこ取りができました。しかし、コードのすべてを 値型 で記述するには困難があります。「値型中心の世界を実現」する軸は、そのような困難を乗り越えるために Swift が取り入れた仕組みや提供している機能についての話でした。
- [第 1 章 {{ site.data.book.chapters[0].name }}]({{ site.data.book.chapters[0].path }})
そのような困難の一つがコレクションでした。
コレクションは、その性質から多くの言語で 参照型 として実装されています。コレクションはコードのいたるところで使われるため、コレクションが 参照型 であることは、 値型 だけでコードを書くのが困難であることを意味します。
Swift 標準ライブラリのコレクションは、 Copy-on-Write を用いることで 値型 として実装されています。そのため、 Swift ではコレクションも含めて値型だけでコードが書けることを説明しました。
- [{{ site.data.book.chapters[0].sections[2].name }}]({{ site.data.book.chapters[0].sections[2].path }})
もう一つの困難は、状態変更に伴うコードを記述する難しさでした。
単純なケースでは、 値型 は ミュータブルクラス と同じように簡潔なコードで状態変更を扱うことができます。しかし、より複雑なケースでは一筋縄では行かないことがあります。
本書では次の四つを取り上げ、どのようなケースで難しさがあり、それを解決するために Swift がどのような機能を提供しているか、それらを使ってどのように問題を解決するのかを説明しました。
- 安全な
inout
引数 mutating func
- Computed Property を介した変更
- 高階関数と
inout
引数の組み合わせ
- [{{ site.data.book.chapters[0].sections[2].name }}]({{ site.data.book.chapters[0].sections[2].path }})
Heart の図のもう一つの軸が、上方向に伸びる 「値型前提の抽象化を実現」 する軸です。
冗長なコードの重複を避けるために、抽象化は避けては通れないテーマです。 値型 中心のコードでは、 参照型 中心のコードとは異なる方法でコードを抽象化することを説明しました。
- [第 2 章 {{ site.data.book.chapters[1].name }}]({{ site.data.book.chapters[1].path }})
オブジェクト指向プログラミング ( Object-oriented Programming )においては、 継承 を元にした サブタイプポリモーフィズム ( サブタイピング )が抽象化における重要な役割を果たします。しかし、 値型 は 継承 することができません。そこで、 Swift ではプロトコルを用いてコードを抽象化します。
このとき、 値型 中心の Swift では サブタイプポリモーフィズム よりも パラメトリックポリモーフィズム が適していると説明しました。これをプロトコルに焦点を当てて言い換えると、 Swift ではプロトコルを型として用いるよりも、制約として用いるのが適していると言えます。 Swift の標準ライブリでも制約としてのプロトコルが広く使われています。
Protocol-oriented Programming には明確な定義がないですが、本書ではそのようなプロトコルの使われ方に焦点を当てて Protocol-oriented Programming を説明しました。
- [{{ site.data.book.chapters[1].sections[0].name }}]({{ site.data.book.chapters[1].sections[0].path }})
- [{{ site.data.book.chapters[1].sections[1].name }}]({{ site.data.book.chapters[1].sections[1].path }})
パラメトリックポリモーフィズム による抽象化を実現するために ジェネリクス が用いられますが、 ジェネリクス�� は戻り値の型をうまく抽象化することができません。そのため、 ジェネリクス と対になる概念として、戻り値の型を抽象化する リバースジェネリクス が考案されました。さらに、 リバースジェネリクス を簡潔に記述するための構文として Opaque Result Type が提案されました。
- [{{ site.data.book.chapters[1].sections[2].name }}]({{ site.data.book.chapters[1].sections[2].path }})
Opaque Result Type は戻り値の型についてのものでしたが、同じことを引数の型についても考えることができます。それが、 ジェネリクス を簡潔に記述するための構文 Opaque Argument Type でした。
- [{{ site.data.book.chapters[1].sections[2].name }}]({{ site.data.book.chapters[1].sections[2].path }})
Opaque Argument Type と Opaque Result Type をまとめて Opaque Type と呼びますが、 Opaque Type はプロトコルを制約として用います。これの対になるものに Existential Type があり、 Existential Type はプロトコルを型として用います。
Opaque Type には some
、 Existential Type には any
というキーワードを修飾子として用いることで、「制約として」・「型として」のプロトコルの違いを明確にすることができました。
- [{{ site.data.book.chapters[1].sections[2].name }}]({{ site.data.book.chapters[1].sections[2].path }})
このように、本書は Value Semantics と 値型 を原点に、「値型中心の世界」と「値型前提の抽象化」の実現という二つの軸で、 Swift という言語の Heart を説明してきました。
Swift は決して難解な言語ではないですが、 参照型 中心の言語が多い中では、 値型 を中心とした特徴的な言語だと言えます。言語を使いこなすには、その言語独自の考え方を理解することが欠かせません。
本書が Swift という言語を理解する手助けになったなら幸いです。
{% assign prev_item=site.data.book.chapters[1].sections[2] %} {% include pager.html next=page.next_item prev=prev_item %}