Swiftの特徴
Swiftを発表翌日にいじり倒してみたところ、次のような印象を受けました。
- 不変型を扱いやすくすることで、プログラマにプログラムの状態を排するように導いている
- 型のチェックが厳密になったことで、プログラムがランタイムエラーを起こす可能性が少なくなっている
- 関数型言語の性質を積極的に取り入れている
この新言語に触れた人は、それぞれ違った印象を抱かれることでしょう。Swift言語の作者によれば、Objective-C, Rust, Haskell, Ruby, Python, C#, CLUなどから影響を受けているとのことですが、「あの言語にそっくりだ」「この言語にそっくりだ」という印象は、その人が深く知っている言語によって変わってくるのでしょう。
本稿では、iPhone/iPadやMacのアプリケーション開発で使われてきたObjective-Cと比較しつつ、この新言語の特徴について解説していきます。そのため、想定読者は「Objective-Cでの開発経験者」です。また、紙幅の都合上「関数型言語を触ったことがある方」も想定読者に含めています。これらの言語に未経験の方は、雰囲気だけでもつかんでいただくか、用語などを調べながらお読みください。
宣言・型
まずは、プログラミング言語の最も基本的なところである変数の宣言と型から話を始めましょう。
変数・定数
Swiftには、変数・定数を宣言する方法が2つあります(「//」以降はコメントです)。
var count = 10 // 変数の宣言 let name = "John" // 定数の宣言 count = 12 name = "Sam" // コンパイルエラー
varを用いて宣言した変数は、何回でも代入することを許容します。変数の型が同じであれば、何回でも代入を繰り返すことができます。
一方、letを用いて宣言した定数は、再代入を許しません。letを用いると、状態、副作用を極力排する方向にコードを記述できます。
状態、副作用を排すると何がうれしいかについては、次回以降のクラス・ストラクチャの解説で述べます。記事の主題とは異なるので詳細には説明しませんが、気になる方は、「副作用 プログラム」をキーワードに検索してみてください。バグを排するプログラミング技法に関する見識を得られるでしょう。
リテラル・データ型
Swiftでは、リテラルを次のようにして扱うことができます。
let number = 10 // Int型リテラル let version = 3.1 // Double型リテラル let string = "string" // String型リテラル
次のような記法により、任意の式をStringのリテラル宣言として文字列中に埋め込むことも簡単にできます。
"\(式)"
この式の中に定数を入れた例を見てみます。
let versionString = "version \(version)" // version 3.1
Swiftでは、基本的なデータ型の変数・定数も値型(Value Type)のインスタンスとして提供されます。Objective-CにはNSInteger, CGFloat, BOOLなどのプリミティブ型がありましたが、これらの変数はオブジェクトではないため、インスタンスメソッドを呼ぶことはできませんでした。
次のコードでは、Int型にメソッドを追加し、それを呼び出しています。従来ではプリミティブ型であったはずの整数型の変数から、メソッドを呼び出せることがわかります。
extension Int { func negate() -> Int {return -self} } let minus = -10 let plus = minus.negate() // plus = 10
ここでは、本稿の後の節で解説するエクステンションの機能を使って、既存の値型にメソッドを追加しています。今はObjective-Cにおけるカテゴリのようなものであると考えていただいて差し支えありません。
Swiftの代表的な値型には、Int(整数型)、Double(浮動小数点数型)、String(文字列型)、Character(文字型)、Bool(真偽型)があります。
オブジェクトには、値型(Value Type)と参照型(Reference Type)の2種類があり、前者は値代入の際にオブジェクトのコピーが渡されるのに対し、後者は値代入の際、オブジェクトへの参照が渡されます。