スコープとは
変数や定数、また関数などには使用できる有効範囲が存在します。
その有効範囲がスコープです。
スコープはその範囲に応じて、
グローバルスコープとローカルスコープに分類されます。
また、同じスコープ内に同じ名前を複数存在させることは出来ません。
ローカルスコープ
局所的に使用されるスコープをローカルスコープと言います。
局所的と言われてもよくわからないと思いますので、
関数ないで宣言された変数のスコープはローカルスコープだと思っていいと思います。
また、ローカルスコープは、そのスコープ内でのみ利用可能で、
外部からの参照は出来ません。
下記の例は、関数testMethod()内で定数aを宣言していますので、
関数内でしか定数aを使用することは出来ません。
関数内というのは、
func testMethod(){ } の { }で囲まれた範囲になります。
func testMethod() {
let a = 10
print(a) // 10
}
print(a) //コンパイルエラー
グローバルスコープ
プログラム全体から参照できるスコープをグローバルスコープと言います。
グローバルスコープで宣言された変数や定数は、ファイル外も含めてどこからでも参照できます。
下記の例は定数globalを定義し、関数の内部と外部から参照しています。
let global = "global"
func testMethod() {
print(global) // global
}
print(global) //global
グローバルスコープとローカルスコープを学ぶと、
わざわざ分けないで全てグローバルスコープにしてしまえばいいのではないか。
と思ってしまったので調べたところ、
グローバルスコープで宣言された変数や定数は、
どこからでも同じ名前で参照でき、意図しない変更を招きやすいらしいです。
確かにその通りだなと思いました。
なので、その恐れがある変数はローカルスコープに記述するか、
ローカルスコープに宣言された変数矢定数よりも説明的な命名をして
グローバルスコープ内に記述する必要があると思います。
スコープの優先順位
ここで一つ疑問が出てきました。
それは、グローバルスコープとローカルスコープに同じ変数名があったらどうなるのかです。
コンパイルエラーが起きるのか、もし起きないとしたら優先順位はどうなるのか。
同じスコープ内に同じ変数名は宣言できませんが、
グローバルスコープとローカルスコープや、違うローカルスコープ内に同じ変数があった場合はどうなるのか。
結論として、コンパイルエラーは起きませんでした!
なので、優先順位をはっきりと理解しないと、間違った処理を書いてしまう恐れがあります。
肝心の優先順位ですが、下記のようになりました。
let a = "global"
func test() {
let a = "local"
print(a) // local
}
print(a) // global
まず、グローバルスコープとローカルスコープに同じ名前の定数aを宣言しました。
問題なくコンパイルはできました。
次に、グローバルスコープとローカルスコープで、
print()関数を使用して定数aの値を出力したのですが
グローバルスコープのprint()関数はグローバルスコープの定数aを参照
ローカルスコープのprint()関数はローカルスコープの定数aを参照
という結果になりました。
グローバルスコープのprint()に関してですが、
最初の方で記載した通りローカルスコープの定数aを参照できないことは知っていたので、
想定通りの結果になりました。
ローカルスコープのprint()は、グローバルスコープも参照できる立場ですが、
優先順位的には同じローカルスコープが優先されるらしいです。
皆さんも気をつけてください。
以上、ありがとうございました!