Swiftの変数と定数に関して、わかりやすく徹底解説していきたいと思います。
変数・定数とは
変数と定数というのは、プログラム内でデータを保持するためのものです。イメージ的には入れ物です。
その入れ物は2種類あって、自由に出し入れできる「変数(variable)」という入れ物と、一度入れたら変更できない「定数(constant)」という入れ物があります。
変数と定数の宣言
宣言というのは、初めて入れ物を作る(定義)ことをいいます。変数はvar、定数はletで定義します。
変数の宣言
以下は変数の宣言です。varから始めて、変数名、: 、型名と記述します。
var 変数名: 型名
以下の例では、一行目は、ageという変数名で、Int型(整数)で宣言しています。二行目は、nameという変数名で、String型(文字列)で宣言しています。これらは、初期値を代入していないため、空の入れ物を定義しています。
var age: Int var name: String
以下の例では、上記の例に初期値を代入している宣言の仕方です。一行目は、25という整数が入ったInt型(整数)のageという入れ物を定義しています。二行目は、太郎という文字列が入ったString型(文字列)のnameという入れ物を定義しています。基本的には初期値を入れた方が扱いやすいので、初期値入れるようにしましょう。
var age: Int = 25 var name: String = "太郎"
初期値がある場合、型名は省略できます。Swiftは、型推論(type inference)という仕組みがあり、最初に代入したものから型を自動的に決めることができます。一行目は整数の25を代入しているため、整数のInt型になります。二行目は文字列の"太郎"を代入しているため、文字列のString型になります。ちなみに、: Intや、: Stringのことを、型アノテーション(type annotation)と呼びます。
var age = 25 var name = "太郎"
一般的な書き方ではありませんが、,を使うと、複数の変数を定義することができます。以下の例では、Double型(小数)のheightとweightを宣言しています。heightは、weightの型アノテーションにより、Double型になります。
var height, weight: Double
また、一行で異なる型の宣言も可能です。初期値を代入するか、型アノテーションをつけます。
var age = 25, height, weight: Double, name = "太郎", birthY, birthM, birthD: Int
定数の宣言
以下のは定数の宣言です。letから始めて、変数名、: 、型名と記述します。
let 変数名: 型名
最初がletかvarなだけであって、上記で解説したvarの宣言の仕方と変わりはありません。
let age: Int let name: String
変数と定数の宣言エラー
letと変数名(定数名)の間にスペースがない場合、エラーになります。変数名と:、型名の間のスペースについてはエラーになりません。しかし、基本的には、変数名: + + 型名としましょう。
letage: Int // スペースがないためエラー let age : Int // OK let age: Int // OK let age :Int // OK
以下のように、変数名にスペースを入れるとエラーになってしまいます。以下の場合myAgeというふうにしましょう。
let my age: Int
変数と定数の命名規則
変数や定数名には、スペース以外なら、日本語でも絵文字でもつけることができます。しかし、基本的には、英数文字で記述するようにしましょう。そして、小文字から始めましょう。そしてさらに、複数の単語がある場合は、次の単語の頭文字を大文字にしましょう。これは、ローワーキャメルケースといいます。例えば、クリティカルヒットした数を数える値を宣言する場合は、criticalHitCountというふうにしましょう。ちなみに、スペース以外ならといいましたが、1criticalHitCountというふうに数字から始めるのもNGです。
var criticalHitCount = 0
値の代入
次は、値の代入方法について解説していきたいと思います。変数や定数に値を代入するには、=を使います。=は、同じというイメージが強いですが、プログラミングでいう=は代入を表します。
代入の仕方
以下の例では、ageというInt型の変数を宣言し、その後でageに20を代入しています。そのため以下の2行を実行すると、ageには20が入っている状態になります。
var age: Int age = 20
変数の場合は何度も代入(上書き)が可能です。プログラムは基本的に上から順番に実行されるので、以下のコードは、最終的にageが23になります。
var age: Int age = 20 age = 21 age = 22 age = 23
式の代入も可能です。1+3を代入しているため、aは、4になります。
var a: Int a = 1 + 3
定数や変数を、定数や変数に代入することも可能です。1が入ったaをbに入れています。よって、bは1になります。では、bに代入した後、aはどうなるのかというと、aは空にはなりません。変数、定数を代入するのは、渡すというよりかは、ハンコみたいなイメージです。
var a = 1 var b = a // 1
代入エラー
以下のコードを見てください。ageに代入している上の二つの行は、エラーになります。=の左右にはスペースを入れるようにしてください。入れないのであれば、両方入れないようにしてください。理由としては、age= 1というふうに書くと、ageの後置演算子だと認識してしまうからです。逆にage =1というふうに書くと、1の前置演算子と認識してしまいます。算数で例えると、3 - 1だと、2と割り出せますが、3 -1だとどうでしょう?ただ3と-1と書いてるだけです。-と1の間にスペースがないため、-は1のものになってしまいます。プログラムの=もこれと全く同じです。
var age: Int age= 1 // コンパイルエラー age =1 // コンパイルエラー age=1 // OK age = 1 // OK age = 1 // OK age = 1 //OK
後ほど詳しく解説しますが、プログラミングには型というものが存在します。要は値の種類です。変数や定数に値を代入するには、その変数や定数と同じ型でないといけません。以下のコードは、ageという変数に、文字列の"20"を代入しています。そのためエラーになります。これはSwiftの文法エラーで、コンパイルエラーと言います。
var age: Int age = "20" // エラー
以下のケースもエラーになります。nameはString型のため、Int型の10を代入することはできません。もし10が、"10"のように、ダブルクォーテーションで囲われていたらエラーになりません。
var name: String name = 10
以下のケースもエラーになります。理由としては、aの初期化が行われていないためです。aに何らかの値が代入された後であればvar b = a + 1はエラーになりません。
var a: Int var b = a + 1
変数と定数の違い
ここまで変数と定数を解説してきました。では、次に変数と定数の違いを解説していきましょう。冒頭でも言いましたが、変数は変更できる入れ物で、定数は一度入れたら変更できない入れ物です。
varで宣言された変数は、何度書き換えてもエラーになりません。
var a: Int a = 1 a = 2 a = 3
しかし、letで宣言された変数は、一回のみ代入可能で、2回目の代入はエラーになってしまいます。
let b: Int b = 1 b = 2 // エラー let a: Int = 1 a = 2 // エラー
変数と定数の使い分け
全て変数で良いのでは?と思った方がいると思います。プログラミング始めたては私もそう思いました。全て変数でも、プログラムはかけます。しかし、危険なプログラムになってしまいます。理由としては、例えば、変えるとエラーになる値があるとしましょう。その値をvarの変数で宣言してしまっていると、意図せず変更してしまったり、自分以外の人が変更してしまったりします。そのため、こういう値はletで宣言すべきです。プログラマーはvarで宣言していれば変更していい値、letで宣言していれば変更しない値と認識します。
また、Xcodeの機能として、一度も変更していない値の場合、letで宣言すべきでは?という警告が表示されます。

逆にletで宣言された定数を変更しようとすると、エラーになりますが、以下のように、letをvarに修正しますか?という提案をしてくれます。Fixを押すとletがvarに変更されます。

