Edited at

【Swift】定数と変数の宣言に関する基本的な挙動


この投稿は何?

Swiftにおける変数と定数の宣言・定義の挙動について、調べたことを忘備録として残しておきました。


環境

macOS10.15 Catalina beta9

Xcode11


ハンズオン

まず最初に、宣言と定義について自分なりには次のように解釈しています。


  • 宣言: 値を割り当てるオブジェクトの名前とそのデータ型を決定すること。

  • 定義: 宣言に加えて、具体的な値またはnilを割り当てること。

上記を踏まえて、Playground環境で実行したコードは下記の通りです。


Variables 変数の挙動

変数として宣言されたオブジェクトには、何度でも新しい値を割り当てることができます。

ただし、具体的な値を割り当てる前にアクセスすると、エラーになります。

これは、未初期化状態であることが原因です。


変数オブジェクトを宣言して、値を更新する

var number: Int // declared Integer type variable.

number // ERROR: variable 'number' used before being initialized number
number = 123 // number is assigned value.
number = 321 // number is assigned value agein.

変数オブジェクトをオプショナルとして宣言します。

すると、宣言された時点で nil自動的に既定値として割り当てられることが確認できます。


オプショナルの場合

var optionalNumber: Int? // declared Optional Integer type variable.

optionalNumber // nil is assigned as default value.
optionalNumber = 456 // assigned new value.


Constants 定数の挙動

定数オブジェクトの挙動です。

オブジェクトを宣言した後は、1度だけ値を割り当てることができます。

やはり、既定値を割り当てる前にアクセスすると、エラーになります。


定数オブジェクトを宣言して、値を割り当てる

let message: String     // declared String type constant.

message // ERROR: constant 'message' used before being initialized message
message = "Hello" // Constant, but can be assigned a value only once.

以下のコードでは、宣言と同時に既定値を割り当てて、定数オブジェクトalphabetを定義しています。

既定値として値を一度、割り当てたので、この定数alphabetの値は変更できません。


定数オブジェクトを定義する

let alphabet = "abc"    // define a String type constant.

alphabet = "defg" // ERROR: Cannot assign to value

今度は、オプショナルの場合です。

オプショナルの定数オブジェクトoptionalAlphabetを宣言します。

変数のオプショナルオブジェクトでは、既定値としてnilが自動的に割り当てられていました。

ところが、定数のオプショナルでは既定値が割り当てられていません。

optionalAlphabetにアクセスすると、未初期化状態のエラーが警告されます。


オプショナル定数の場合

let optionalAlphabet: String?   // declared Optional String type Constant.

optionalAlphabet // ERROR: constant 'optionalAlphabet' used before being initialized
optionalAlphabet = "ABC" // assigned default value.

定数オブジェクトに対して自動的にnilを割り当ててしまうと、1度目の値を割り当てたことになり任意の値を割り当てられなくなってしまいます。

そのため、このような挙動になっていると考えられます。


考察

安全を謳うSwiftプログラミングでは「まずは定数で」というコンセプトがあります。

その後、値を変更する必要が発生したら、変数オブジェクトに修正するのが常套手段です。

変数オブジェクトはオプショナルとして宣言すると、自動的にnilが既定値になります。

しかし、定数オブジェクトがオプショナルな場合、意図的に既定値を割り当てないとエラーになります。

呼び出すだけでエラーになるので、nilと比較することすらできません。

ビルド前の静的エラーとして検出されるので、それほど危険なわけではありませんが覚えておきたい挙動です。