この投稿は何?
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
と比較することすらできません。
ビルド前の静的エラーとして検出されるので、それほど危険なわけではありませんが覚えておきたい挙動です。