序
プログラミング......それはコンピューターと人間の間を橋渡しするもの。
これからのデジタル時代には欠かせない技術ですね。
ですがはじめてそれを学ぶ人にはその概念はかなりわかりにくいもので、近年では「プログラミング的思考」を学ぶためのビジュアルプログラミングなんかも生まれたりしているほどです。
またiOSやAndroidなど、次第にデジタルなモノ作りの間口が広くなってきた結果、一応プログラミングはしてるし、モノも作れてるけど実際どういうことなのかわからない...というような人も出てきています。
ということで今回は中学当時苦労して考えて理解していった時の気持ちをなるべく思い出し「誰でもわかる」、そんなプログラミング入門記事を目指して書いていきたいと思います。
是非、今一度プログラミングを理解する手助けとしてお使い下さい。(※ところどころ独自の用語を設定して使用しています。そのような単語は一般的用語でないので調べても出てこないと思うので意味が知りたいという場合はコメントでお知らせください。)
第0章 そもそもプログラミングって?
1. プログラムとは?
programmingという単語は一般に「計画する」という動詞の現在進行系と解釈することができるように、プログラミングという行為はそもそも「計画をたてる」という行為の一つであるといえます。
つまりコンピューターがなにをするかという計画をたてる、それがプログラミングの本質です。ただよくわからない単語を並べて文章をつくっているわけでも、暗号をつくったり数式を解いたりしているわけでもなく、あくまでコンピューターがどう動くべきかを計画だてているのです。
2. 実際にどう動くの?
人間がプログラム言語でプログラムを書くと、コンピューターはまず自分にわかる言葉へとそれを翻訳します。これをコンパイルと言います。英語で書けばcompileで、まさに「翻訳する」という単語です。(インタープリタ言語というように分類される言語に関してこれ以降の話に少し違うところも出てきますが、今回はSwift編ということであくまでSwiftに限った話で進めていきましょう。)
このコンパイルをするアプリケーションとしてSwiftの場合はXcodeがあげられます。このようなアプリケーションをコンパイラと呼びます。といってもXcodeの場合はエディタなどの機能も含んでいるので実際には**統合開発環境(IDE)**と呼ばれる存在になりますね。マルチプラットフォーム化が進んできてUbuntuなどのOSではXcodeとは違うアプリケーションがSwiftのコンパイラになっていますが今回は置いておきましょう。
実際には、まずXcodeはSwiftを中間言語とよばれるものに変換した後、最後に機械語というものに変換します。機械語は0と1のみで記述されており、これによってコンピューターは動き、計算し、最終的な結果に行き着きます。(※図中のコードはお互いに対応してませんのでその点の指摘は受け付けかねます。また中間言語の図に関してはそれ自体に対する知識があまりないので代わりにアセンブリ言語チックなものを表記しておいただけで本来のものとは違います。)
3. コンピューターの動き
先程「コンピューターが動き、計算し、」と曖昧に言いましたが、コンピューターが実際にやっているのは回路のスイッチのオンオフの切り替えです。これによっていろんな計算をしている...というと到底想像がつかないと思いますが、とにかくそういうものだと思ってください。詳しくは本題からそれるので興味のある方は論理回路などのワードで調べてみたり、実際に大学の授業などで学んでみましょう。
さて、どうしてこんなことにまで言及したかというと、コンピューター自体が本当にできるのは簡単な2進数の足し算引き算や論理演算だけということをいいたかったからです。プログラミング言語はそういった簡単な演算の組み合わせで実際にやりたい処理を直感的に記述するためにつくられているのです。
4. この章のまとめ
少し長かったですがこの章を通してまずプログラミングとはそもそも何かということについて説明しました。プログラミングをする上でこれらの知識は必ずしも必要なものとは言えませんが、この認識があるか否かでプログラミング自体への理解度はかなり向上すると思うのでぜひ覚えておきましょう。
第1章 プログラミングの基本要素
1. リテラル
まず本当の基礎の基礎はリテラルと呼ばれる存在です。これは数字や文字列、真理値、nil
などといった値としてあつかわれるもの一般を指します。
第0章で言及した通り、プログラムは最終的に2進数に変換されてしまうので、プログラムで書いた数字も文字列も真理値もすべて実際のところはその値を表す表現にすぎません。
こう言うと混乱してしまうかもしれませんが、この認識をもつことによってこれらの表現がプログラム上で想定された動きしかできないのだということを理解してほしいです。人間でも足し算と言われたら無意識に数字同士であればその値を足したものだと考えますし、文字の並んだもの同士ならそれらをつなぎ合わせることと勝手に解釈しますよね?(ちょうどPPAPのように)
それと同じことで、コンピューターも人間とは少しルールが変わるかもしれませんがこれらが表現であることで、それがどのようなルールに従う値を表すのかを解釈し扱うことができるのです。(このような処理がSwiftでは型推論というコンパイラの機能として実現されています。)
2. 型
せっかくなので次は型について見ていきましょう。先程述べたリテラルがどのようなルールに従うものなのかということについて分類し、名前をつけたのが型というものです。具体的には簡単なものならInt
やFloat
、String
などがそれにあたります。
Xcodeが賢いというか、Swiftが賢い言語なので基本的には型を明示しなくてもプログラムの文脈をみてどの型かを判断してくれるのですが、一般的には型を明示することでそれがどういうルールに従うのかということをコンピューターに教えることになります。
例えばSwiftでnil
を含んだオプショナルという概念はそれ自体が一つの型なので、その扱いを間違えるとXcodeは「この使い方はルールとあってないよ〜」とエラーをはきます。ここらへんの詳しい話はまたのちほど。。。
3. 変数・定数
変数・定数は値の入った箱と比喩されることが多いですが、ここまでの説明を読んでくれた人に対してならまた違った言い方をすることができます。つまり変数・定数とはプログラムの中で自分でルールを決めて名付けた表現なのです。例えば
var a: Int = 0
とすれば、
これからこのプログラムでは
a
をInt型のルールにしたがった変数にするよ!つまり、数字だったらいつでもa
が表す値をそれで書き換えていいよ!!最初にa
があらわす値は0にするよ。
という意味になります。よってそのプログラム上では(というと本当は語弊がありますが...)a
という文字はa
に入れた(代入した)値と同じ意味になります。一方
let str: String = "Hello"
とすれば
これからこのプログラムでは
str
をString型のルールにしたがった定数にするよ!str
が表す値はもう変えられないよ!!
という意味になります。よってそのプログラム上ではstr
という文字はHelloという文字と同じ意味になるのです。
ちなみに変数と定数の違いはこのように後で値が変えられるか変えられないかの違いでしかありません。重要なのはこのように定義されたプログラムを、その時点でその変数または定数が表している値に置き換えて読んでいくとプログラムがぐっと人間の言葉に近づくということです。
このようにプログラムを自分で解釈していくことをコードリーディングといい、他人のコードをみて勉強したり、あるいは自分の書いていたコードをみてもう一度何をしているか理解しなおすなど様々な場面で役にたちます。プログラミングについて一通りわかってきたら簡単なものからでいいのでコードリーディングしてみるといい勉強になると思います。(慣れてくれば所詮プログラムはある決まりに従って書かれた処理の羅列でしかないので、コードを読む方が解説を読むより決まりなども実例でわかるようになりますし理解もはやくなります。)
4. コメント
プログラムの本筋からは外れてしまいますがコードリーディングについても言及したところでせっかくなのでコメントについても。
コメントはプログラムの中で人間は読むけど、コンピューターにやってほしいことなわけではないというものを書く時にやります。Swiftだとこんな感じでした。
// この行一行分はコメントになる
/*
この間は全部コメント
だよ〜
*/
ここはコメントじゃない
本来であればこれはコードリーディングでほかの人や未来の自分がそこで何をやっていたのかわかりやすくする説明をつけるためにあるものですが、コンピューターはあくまでその中身にはまったく関与しないという性質から、プログラムの中で一時的に実行したくないコードをコメントにして飛ばすというコメントアウトという行為が生まれました。
Xcodeなどではこの他にもコメントを特定の形式で書くとそれを説明として使う人に表示してくれたりといった機能があったりしますが、それはライブラリなどを自作するようになってから考えればいいでしょう。(ライブラリとは、ある一連の処理を他のところでも使えるようにまとめたものです。Swiftでの作り方はこちらが詳しいです。)
とにかくコメントはあくまで人間への説明用にすぎないので、過度にコメントアウトしたコードを残しすぎてしまうと逆にコードが読みにくくなったりするので注意しましょう。(何行も関係ないこと読んでたら直前までなにやってたかなんて忘れちゃいますよね汗)
5. 配列
さて、コメントへのコメントが終わったところでみなさんが忘れないうちにプログラミングの基本要素の説明に戻りましょうか。
続いては配列に関してです。これも変数・定数が入る箱と言ってしまえばそれまでなのですが、別の方向から説明してみましょう。
配列は同じ型のものを複数個まとめたものを簡単に表す表現です。Any
などあって別に違う型でも配列に入るじゃないかみたいな意見もあると思いますが、実際Any
も一つの型なのでやはり同じ型のまとまりです。たとえばこんなものを
var a1: Int = 1
var a2: Int = 2
var a3: Int = 3
var a4: Int = 4
var a5: Int = 5
var a6: Int = 6
このようにまとめることが出来ます。
var a: [Int] = [1, 2, 3, 4, 5, 6]
そしてこれによってa[0]
とプログラム上で書くと1と同じ意味に、a[3]
が4と同じ意味になるのです。
この0から数える0-indexedという配列の決まりは初心者の苦手とするところの一つですが、その理由を書くと少し長くなってしまうのでここでは割愛します。
このようにプログラミングでの概念はすべて「あるものをあらわすための表現」です。それを具体的にイメージする上で箱などの比喩が役立つこともありますが、それはあくまで自分で考える時の助けになるだけであって、あまり突き詰めると逆にわからなくなってしまうので注意しましょう。プログラムの意味を理解するには、その表現がどういう概念なのかということを理解するのではなく、その表現がコンピューターによってどういう風に置き換えられるのかを把握することが重要なのです。
6. 制御構文
次は制御構文とくくられるものについて見ていきます。
6-1. 条件分岐
まずは条件分岐とよばれるものたちです。一番の代表格はif文ですね。以下のように使います。
var a: Int = 2
if a == 2 {
// aが2の時の処理
} else if a == 1 {
// aが1の時の処理
} else if a == 3 {
// aが2の時の処理
} else {
// それ以外のときの処理
}
さてこれをコードリーディングして上から日本語にしていってみましょう。するとこうなります。
まず
a
をInt型の変数として定義しよう!最初の値は2だよ!もしaが2と同じ意味を表していたらこの波括弧の中身を実行しよう。でももしa
が2を表してなくて、1と同じ意味だったら二個目の波括弧の中身を実行しよう。そうでもなくて、つまりa
が2でも1でもなく、3と同じ意味だったら3つめの波括弧の中身を実行しよう。もしこれら全部が当てはまらないなら、四個目の波括弧の中身を実行しよう。
かなりしつこく「波括弧の中身」というふうな表現をしました。これはこれから話す制御構文しかり、あるいは後でいうメソッド、クラスなど、それをコンピューターが解釈するときに影響してくるのが波括弧でくくられたかたまりの中だけだということを認識してほしいからです。このかたまりをブロックといいます。
具体的にはこのif文、else-if文、else文というのはある条件に当てはまるかを判断してそれで選ばれたブロックだけを実行するという文です。このようにこっからここまでは条件におうじてコンピューターが解釈するものを変えますよということをコンピューターに教えるための文法を一括りにして条件分岐と言い、その時に選ばれる単位となるのがブロックなのです。if文自体はコンピューターに「もしこうだったらあれして、こうだったらそれして、そのどれでもなかったらこれをして」というための文とも表現できますね。
『文法』なのでその書き方によって少し意味の解釈が変わってくるだけで日本語とまったく変わらないという認識をもちましょう。きっと身近なものになってくるはずです。
その例は他にもあげられますが一旦この章では具体的なところには踏み込まずに次に進みましょう。
6-2. 繰り返し文
繰り返し文はその名の通り、同じことを複数回繰り返したい時に使います。例えば「掛け算を使わずに10回1を足す」というプログラムを書くのにこんなにいちいち書きたくないですよね?
var num: Int = 0
num = num + 1
num = num + 1
num = num + 1
num = num + 1
num = num + 1
num = num + 1
num = num + 1
num = num + 1
num = num + 1
num = num + 1
ですから次のようにするわけです。ここではfor文を使ってみましょう。
var num: Int = 0
for i in 0 ..< 10 {
num = num + 1
}
このように一気に同じことを意味するプログラムなのに7行も省略できましたね。このように簡潔にしていくことは抽象化とよばれる行為の一種とも言えて、プログラムはいかに抽象的にしていくかという作業であるとも言えます。これがプログラミングの理解を難しくしている一因であるとも言えますね。(具体的なことのほうが簡単なので。算数が具体的なもので数学が抽象的なものと考えるとわかりやすいかもしれません。)
さて話を戻しましょう。先程のコードをコードリーディングする時、またブロックが役に立ちます。つまりこれをコンピューターが読む時コンピューターは「おっfor
が出てきた。ということはここから繰り返しだな。i in 0 ..< 10
をしながら繰り返せばいいのか。あ、波括弧が登場したぞ!ということはこっから波括弧が終わるまでを繰り返せばいいんだな。」といった感じで解釈していくのです。こちらも詳しくは後ほど。
7. メソッド
さて、次は**メソッド(関数)**についてです。
ここまで書いてきた概念とその文法を知っていれば基本的なプログラムは書くことは出来ます。ですがそれが複雑になっていくにつれて、同じものを何回も書いていてめんどくさいということが出てきます。これを解決するのがメソッドです。抽象化の手段の一つですね。
Swiftではfunc
からはじまるとそれがメソッドだと解釈されます。例えば
func add(a: Int, b: Int) -> Int {
return a + b
}
とすればadd(1, 2)
が3と同じ意味になりadd(10, 39)
が49と同じ意味になります。
メソッド自体は処理のかたまりで、よく工場で例えられたりしますしそれだけなのですがよく聞くのは引数と返り値(戻り値)というのがよくわからないという声ですね。
やはりこれも表現の決まりに名前を付けただけなので概念を理解するとなるとややこしいのですが、言い換えることなら簡単です。次のリストを読んでみてください。
- メソッドは引数を受け取ってごにょごにょした結果を返り値として返す
- 引数が入力で、返り値が出力。メソッドは入力から出力に変換するもの。
- 引数がAppleとPen、返り値がApplePen、メソッドは手を「おぅん」っていいながらあわせること
もうわかりましたね(雑)。ともかく大事なのはあくまでコンピューターが読み取るための表現でしかないこと、とにかく無駄なことはしたくないという発想から生まれているということです。それがプログラムでありプログラミング的な思考の根幹にある欲求なのです。
8. クラス・構造体・列挙体
ここまでお膳立てしてくればこれらの説明も楽勝です。
クラスなどは大抵の場合「クラスは同じようなものの設計図で、それをインスタンスっていう実体のあるものにして使うんだよ〜」みたいな説明がなされますが、これら3つは全て無駄に同じようなことを繰り返し書きたくないという気持ちから生まれたプログラマが自らつくったルールをもった型を定義するための文法でしかありません。
事実、Swiftにある多くの既存の型もこれら3つのいずれかによって定義されています。そう、なんでこんなものがあるのか?どうしてこれはこうなのか?みたいに難しく考えなくていいんです。いや、むしろそう考えること自体が間違っているかもしれませんね。あくまで自分たちでルールを決めるための作法でしかないのですから。
9. この章のまとめ
最後大分投げやりになっているように見えますが、実際のところプログラミングというのはこういうものなのです。つまり、人間が機械語というわけのわからないものを自分たちにわかるようにするためにつくった言語であり、その上での概念も結局は人間の決めたルールであり文法であり表現でしかないんです。
「プログラムを理解すること」はその表現を「もっとわかりやすい表現に置き換える」という行為をするだけで完結します。実際、プログラミング言語を複数習得している人は新しい言語を覚える時、「この概念はこの言語ではこう書いて、これはこう書けばいいんだな。よしわかったぞ。」とすでにわかっているものへと置換する作業を通じて学んでいきます。で、これはつまり色々な言語を覚えると、それだけ一つの概念に対しての具体例が増えていって、自分の中で具体的になっていってより覚えやすくなるということで、だからプログラミングを学ぶ一番の近道は自分の中の具体例を増やしていくことなのです。それがコードリーディングであり、自分でプログラムを書いてみるということであり、それを実行した結果を見てみるということなのです。
これは外国語を学ぶことと同じですね。僕は外国語が苦手ですが、プログラミングは得意です。なぜなら英語のような言語に比べてプログラミング言語はずっと覚えるべき単語も文法も少ないからです。だからプログラミングの概念が自分の中でふわふわしていても諦めないでください。基礎を覚えなおしてください。きっとすぐ出来るようになるはずです。というわけで次の章ではSwiftのここまで解説してきたものの具体的な書き方を見ていきたいと思います。
第2章 世界一丁寧な文法解説
さて、世界一丁寧な文法解説をしようかなと思うのですが、世界一丁寧ってどんなのかなって。
そうなった時にQiitaのMarkdownだけじゃたりないなってなったので画像を作ることにしました。
スライド形式になっているので、自由にダウンロードしてご活用ください。改変なども自由ですがネット上で使う際には各画像に入れているコピーライト表示だけは消さないようにお願いします。。。
1. 型
型には他にも色々あります。もちろん前章で述べた通り自分で型をつくることもできます。
ここにあげたような基本形だけではなく、色々しらべてどういうものか分かっておくことも重要かもしれませんね。
また前章でも言及した通りオプショナル型はスライドに書いたように配列に似た一つの型になっています。ここらへんは今流行っていて様々な記事が出ていますし、以前書いた記事に参考リンクとともに軽くまとめてあるのでそちらを参考にしてください。
2. 変数・定数
接頭辞などの用語は便宜上独自にそう呼ぶことにしました。ここで重要なのはvar
、let
というキーワードが変数・定数であることの目印になるということです。なぜこんなことを言うかというとiOS開発からプログラミングを始めた場合以下のようなものが変数・定数ではないという誤解をしている人がいるからです。
@IBOutlet weak var myLabel: UILabel!
private let MY_KEY = "xxx-xxxx"
ここで付いている@IBOutlet
やweak
、private
などは一般に修飾子などと呼ばれたりしています。その役割は様々ですが、その名の通りどちらかというとそれが何かというよりもそれがどういう性質を持ってなければいけないかを示すためのものです。特に後ででてくるメソッドについたりする@IBAction
とここで出てきた@IBOutlet
、その他にも@IBDesignable
など@
ではじまるものがいくつかありますがこれは基本的にコードとストーリーボードやxibなどの要素を繋ぐ役割を担っているのであって、これがついていないからUI要素ではないということは無いので注意しましょう。(コードからもUI要素は追加できます。)
3. 配列
配列は理解すればとても簡単ですが、理解するまでが難しいです。理解していない間は複数の変数と定数を宣言して同じことを実現できるのでそちらに頼ってもいいでしょう。
配列はもちろん同じようなものをまとめてコードを簡潔にするという役割もありますが、特にSwiftの配列は変数で宣言してあれば可変長、つまり大きさを変えることができるのでそのような時に真価を発揮します。
たとえば毎月のお小遣いをまとめる配列があったとして新しくお小遣いをもらった場合は以下のように書けます。
var money = [1000, 5000, 20000, 100, 3000]
print(money[2]) // 20000
print(money[4]) // error: index out of range的なものがでる
money.append(500000)
print(money[4]) // 500000
もちろん削除することも可能です。使いこなしたい方は是非調べて色々使ってみるといいかもしれません。(※一般的注意としてSwiftでコードを調べる場合はSwiftのバージョンや記事の更新時期などに注意して調べるようにしましょう。)
4. if文・switch文
if文、switch文ですがまず最低限if文はマスターしてほしいものです。概念がまだふわっとしているなという人はif文のスライドに書いた図でイメージするようにしてみてください。else if
やswitch
などはif文をより簡単に書くための文法なので最初から完璧に理解しようとは思わなくていいと思います。
条件としては以下のようなものがありますが、型によってこれらが使えず代わりの独自のメソッドが定義されている場合があるので注意してください。(数や文字列に関してはそこまで心配する必要はないと思います。)
// xとyが同じかどうか
x == y
// x < yかどうか
x < y
// x ≦ yかどうか
x <= y
// x ≧ yかどうか
x >= y
5. for文・while文
繰り返しは他にもdo-while文がありますが、基本的にどの文法でも同じことが実現可能です。使い分けがあるのはそれぞれで実現しやすいものが異なるということです。
たとえば10回の繰り返しというのは入門サイトでは以下のように書かれることが多いと思います。
for i in 0 ..< 10 {
}
この時本当はfor文にとってi
や0..<10
は決まり文句ではないのですがそうしてしまえば説明が簡単なのでそのように扱われることが多いです。
ちなみにここでのi
はin
の後に続く配列の要素が順番に入っていく変数でfor文の中でだけ使えるものです。i
などを使わないのならば_
にしても構いません。また他のnum
とかj
とかにしても意味は変わりません。
また0 ..< 10
というのはスライドにも書きましたが、Swiftの便利な省略記法というかなんというかで、0以上10未満の整数を全て一個ずつ入れた配列という意味になります。同じようなものに1 ... 7
みたいな書き方もあって、これなら1以上7以下になります。
重要なのは配列の頭から順番にとってきてその度に中身を実行するという挙動なので覚えておきましょう。
6. メソッド・クロージャー
まずメソッドは以下のように書きます。引数の有無や返り値の有無で少し変わってくるので注意です。もちろん日本語で書かれているところにはそれ自体が入るのではなくて、対応するものが入ります。
// 引数と返り値がある時
func メソッド名(引数ラベル 引数名: 引数の型) -> 返り値の型 {
return 返り値
}
// 返り値が無い時
func メソッド名(引数ラベル 引数名: 引数の型) {
}
// 引数も返り値も無い時
func メソッド名() {
}
// 引数が複数ある場合
func add(a: Int, b: Int) -> Int {
return a + b
}
// 使う時
メソッド名(引数ラベル: 引数に入れる値)
用語を復習しましょう
- メソッド名...メソッドにつける名前。なるべく中で何をするかわかりやすいように名前をつける
- 引数ラベル...メソッドを使う時にどの引数に値を入れるかを示すため書かせるラベルの名前。省略すると引数名が引数ラベルの役割を担う。また
_
とすれば引数ラベルを使わなくてもメソッドを使えるようになる。 - 引数名...メソッドの中で引数として渡された値をあらわすものになる。
- 返り値...メソッドの中でやった処理の結果として外側に返す値
さてこれがメソッドでした。func
が目印です。そしてこれはクロージャーの特別な場合になります。クロージャーは以下のように書きます。
let クロージャー名: (引数の型 -> 返り値の型) = {
引数名 in
// 処理
}
var クロージャー名: ((Int, Int) -> Int) = {
$0 + $1 // $0が一番目の引数、$1が二番目の引数
}
注目してほしいところは何点かあるのですが、まずクロージャー自体は変数もしくは定数としてしか扱えません。逆に言うと引数などで渡すこともできます。メソッドとの違いはこの宣言する仕方の違いが大半なのですが、上の例のようにクロージャーには引数をとるための書き方が何種類かあります。
メソッドをマスターすれば、map
のような関数型プログラミングのメソッドや非同期処理などに出会うまでクロージャーの使い所はいまいちわからないと思いますが、一番肝心なところはクロージャーはなんだか難しい気もするけど実体はメソッドとほぼ同じという認識をもつことです。
7. クラス・構造体・列挙体
クラス・構造体はやはりまとめて覚えてしまうのがいいかもしれません。イラストで直感的な違いは書きましたが、Swiftでの使い分けをもう少し詳しくしりたければこちらの記事なんかが詳しいので読んでみてください。
直感的に理解できたらクラスはViewController
が一番身近な例なのでそれを見てみるのがいいのですが、そういえばViewController
って基本こんな風になってますよね?
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
ここで注目してほしいこの: UIViewController
という書き方が変数・定数・引数の型を指定する書き方に似ているということです。その感覚は決して間違いではなく、クラスも型だとみればこれはクラスの型を指定する書き方になっています。これを一般にはクラスの継承と言います。詳しくは次のプロトコルと一緒に解説したいと思います。ちなみにこの継承というものだけは構造体にはありません。
列挙体は使おうと思わないと使わないですが、スライドに書いた通り使い始めるとかなり便利です。
例えば月の数字を羅列しておきたい時配列で次のように書くことが思いつくと思います。
let month = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
ですがこのように変更が想定されていない配列の場合、むしろ列挙体で次のように書いたほうが後々便利です。
enum Month {
case January
case February
case March
case April
case May
case June
case July
case August
case September
case October
case November
case December
}
これはMonth.January
みたいな感じで使うことになるのですが、もちろん数字が必要であれば以下のように書き直せばOKです。
enum Month: Int {
case January = 1
case February
case March
case April
case May
case June
case July
case August
case September
case October
case November
case December
}
これでMonth.January.rawValue
が1になります。また最初を1にしたことで以降は書いてある順に数字が紐付いていきます。つまりMonth.March.rawValue
は3ですし、Month.December.rawValue
は12です。enum
の時の: Int
はこのようにrawValue
という値の型を指定しており、Int
をはじめString
あたりにするとrawValue
は明示しなくても自動で設定してくれる機能があります。
なぜこのように書くと便利かというと、これは完全にSwiftならではなのですがXcodeで予測変換が効くようになるからです。このように予測変換ができるものはタイプミスが減るという点でとても便利です。
8. protocol・extension
ここからは発展的事項なのでかならず必要ということはありませんが、プロトコルとクラスの継承は比較するとわかりやすいと思うので解説したいと思います。
クラスを設計図だとします。するとまずクラスの継承というのは元となる設計図があってそれに付け足したり書き足したりするイメージになります。一言でまとめれば設計図自体をコピーして書き直すのが継承です。override
は元々設計図にあるものを上書きするという意味です。そして先程のViewController
の例でいけばsuper.viewDidLoad()
というものがあったと思いますがこのsuper
というのが元の設計図を表しています。これで元の設計図にあったviewDidLoad()
というメソッドを実行するという意味になります。
一方プロトコルは設計図が満たすべき条件、仕様書です。仕様書に『何々がなければならない』と書いていたら設計図にそれを盛り込まなきゃいけないのと同じように、プロトコルに『こういう変数とこういう変数とこういうメソッドがある』と書いてあればそれらすべてを実際に書かなければなりません。
具体的な使い方はクラスの継承と同じです。一番身近な例としてUITableViewDelegate
などがあります。プロトコルがあるからこそクラスの『型』だけは複数同時に指定することができるのです。継承は一つのクラスからしかできませんが、プロトコルならいくつ付けてもいいので。つまりこうです。
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
}
ちなみにプロトコルはクラスだけではなく構造体と列挙体に適用することも可能です。
より詳しい書き方はSwift2ですがこの記事なんかがおすすめです。
続いてextension、拡張です。これはクラスの例でいくと設計図に後から付け足す追記になります。付箋をイメージするといいかもしれません。付箋ですからextensionで書くところは別に使わなくても書けてしまうのですが、これがあることによってInt
など元々Swiftにあって直接ファイルがいじれないものも拡張することができます。
またextensionの時点で次のようにプロトコルを適用することもできるのでコードの整理にも役に立ちます。
extension ViewController: UITableViewDelegate {
}
この書き方があるので、世の中にはprotocol-extensionという設計思想的なものが存在しています。
また標準ライブラリの拡張は便利にするという効能もあるのでこの記事のようにコピペするだけで便利になるコードといったものが作れます。
9. アクセス修飾子
最後はアクセス修飾子です。これは今まででてきたものたちがどこから使えて、どこからは使えないかという制限をつけるものです。いくつか見慣れない用語があると思いますが、モジュールは括弧で書いた通りプロジェクトのことです。xcworkspaceは違いますが、同じxcodeprojに入っていれば同じモジュールということになります。ファイルはコードのファイル一つ一つをさします。つまり同じ.swiftファイルの中ということです。
最後のスコープというのは少しむずかしいですが、前章にも出てきた「ブロック」と同じものと思ってもらって構いません。つまりクラスの中だけ、構造体の中だけ、列挙体の中だけ...という感じです。
より詳しくはこちらの記事も参照してください。
10.まとめ
文法解説ということでかなりSwiftに絞った解説になってしまいましたがいかがでしたでしょうか?是非今一度前章と一緒に読んで理解していってほしいなと思います。
クオリティも詳しさもかなりまちまちになってしまいましたが、全体として意識してほしいのは全て最初に接頭辞と表現したそれがなんなのかを示す目印があって、その後に名前を書いて、そして型を指定したり内容を書いたりするという共通の構造があるということです。これが普通の言語(英語とか日本語)の文法に似ているなと思えるようになればマスターしたも同然だと思うので、ぜひ解釈する時に英語とか、英語が苦手なら日本語に置き換えるとどうなるかなと考えてみることをおすすめします。
終わりに
以上自分なりにわかりやすいプログラミング入門記事を目指してここまで書いてきましたが、いかがだったでしょうか?
思いのほか中学時代の自分の思考回路を思い起こすっていうのが難しく、苦戦しましたが自分なりのプログラミングのそれぞれの概念に対する考え方というのは表現できたのではないかなと思っています。
といってもタイトルの通り「誰でもわかるプログラミング入門を目指したい」という理想のもと書かれている記事なので、ぜひわかりにくいところなどあればどんどんフィードバックしていただければと思います。それをもとにブラッシュアップして本当に誰でもわかるプログラミング入門記事になればいいなと思っています。
最後となりますが、この記事をIS17er Advent Calendar2016の最終日の記事としたいと思います。ここまで読んでいただきありがとうございました。
Special Thanks
Life is Tech !のメンターの有志の方々に公開前のレビューをしていただきました。
へむへむ、じんちゃん、レモン、だいふく、ぶんぶん、本当にありがとうございました。
参考リンク
本文中の内容に関する参考記事です。ぜひ読んでみてください。
- Swift中間言語の、ひとまず入り口手前まで
- Swiftでライブラリを公開する
- Swift学習日記#2016/05/26-Optional型について
- Swiftのクラスと構造体の使い分けについてのメモ
- Swift では Protocol を積極的に使おう
- 使うと手放せなくなるSwift Extension集 (Swift3版)
- Swift 3からのアクセスコントロール
さらにこの記事でプログラミングとは何かと言うものを掴み、さらにSwiftを使いこなしたいという方はこちらが網羅的に文法をまとめてあるのでおすすめです。
最後にプログラミングの魅力に気付いてしまった方に非常にオススメしたい、すばらしいサイトを紹介して締めたいと思います。