前回はSwiftについて、どんな言語であるかその特徴などをまとめました。
前回の記事はこちらから。
今回はiOSやMacOSなどのApple製品上のアプリを作成する上で外せないプログラミング言語Swiftについて、どんな言語なのかをまとめていきたいと思います。実際の文法などには触れずに言語の特徴などをまとめていきます。 言語の概要[…]
今回はプログラミングを学ぶときに最初期に学ぶ変数・定数・スコープ・式について、Swiftにおける扱いやそもそもそれって何なの?といったところまでまとめていきたいと思います。
変数・定数
変数・定数とは?
変数・定数とは、一時的に値を格納する箱のような役割を持っています。
格納した値は一定の範囲のプログラム内で参照することができ、値の再利用や演算した結果の格納などに使います。
変数・定数に値を格納する操作を代入と言い、Swiftの場合は代入する値に応じて適切な型の変数・定数を用意する必要があります。
例えば、「1」や「23」など数値を代入したい場合は数値型、「こんにちは」や「Hello」など文字列を代入したい場合は文字列型の変数・定数を用意する必要があり、適切でない型の変数・定数に代入しようとするとエラーになります。(型についてはかなり大事な概念なので別の記事で改めてまとめたいと思います。)
ちなみに、Swiftのように適切な型を用意する必要がある言語を静的型付言語といい、反対に型を意識することなく代入可能な言語を動的型付言語と言います。
変数・定数の違い
変数と定数の違いは何かというと、値の再代入が可能か不可能かという違いがあります。
再代入とは、一度何らかの値を代入した後に違う値で上書きすることです。
変数は再代入をすることができるので、例えば「1」を代入した後に「2」という違う値を上書きすることができます。
定数は再代入ができないので、一度「1」という値を代入した場合、「2」などに変更はできず最後まで「1」が格納されることになります。
「変わる可能性がある値」が「変数」、「定まった値」が「定数」なのでわかりやすいですね。
Swiftでの実装方法
宣言方法
宣言とは変数や定数などを定義することです。
Swiftでは以下のように宣言します。
// 変数の宣言
var 変数名: 型名
// 定数の宣言
let 定数名: 型名
変数名・定数名の部分は任意です。「x」でも「number」でも「taro」でも構いません。
が、その変数・定数の役割がわかる名前をつけるのが一般的です。(合計を表すなら「sum」、税率を表すなら「tax」など)
値の代入
変数・定数へ値を代入する場合は以下のように行います。
// 値の代入
変数名・定数名 = 値
Swiftを含めて多くのプログラミング言語で用いられるのが「=」です。
数学では「等しい」ことを表す記号ですが、プログラミング言語上では「代入」を表すので気をつけましょう。
宣言と値の代入を同時に行う
上記では分けて書きましたが、宣言と代入は同時に行うこともできます。
// 宣言と代入を同時に行う
let 変数名: 型名 = 値
型推論を用いて型名を省略する
Swiftには型推論という仕組みがあり、プログラム側で推測可能な型の場合は宣言時に型名を省略することができます。
// 型推論による宣言と代入
let 変数名 = 値 ←変数の型が代入する値の型に合わせて決定される
実際に使ってみる
実際にSwiftのプログラムを書いて、変数・定数を利用してみます。
変数・定数の宣言と利用
// 変数の宣言 Int型(整数)の変数
var num1: Int
// 値の代入
num1 = 1
// 定数の宣言 String型(文字列)の定数
let str: String
// 値の代入
str = "Str"
// 変数の宣言と代入を同時に行う
var num2: Int = 2
// 型推論による宣言と代入
var num3 = 3 // ← Int型の変数となっている
// 代入した値を取り出して使う
// num1,num2,num3の値を取り出して加算し新たな変数sumに格納している
var sum = num1 + num2 + num3 // 1 + 2 + 3
// 格納された値を取り出し、print()を使って表示させる
print(sum) // >> 6 が表示される
print(str) // >> Str が表示される
実行結果は以下のようになります。
値の再代入
// 変数num1を宣言し「1」を代入
var num1 = 1
print(num1) // >> 1 が表示される
// num1に別の値「2」を再代入
num1 = 2
print(num1) // >> 2 が表示される
//定数strを宣言し「Str」を代入
let str = "Str"
print(str)
//定数に再代入は不可能
str = "Another str"
実行結果は以下のようになります。
型が違う変数への代入
// 変数num1を宣言し「1」を代入
var num1 = 1 // Int型の変数
num1 = 2 // Int型なので「2」は代入可能
num1 = "3" // String型は代入不可能
実行結果は以下のようになります。
ごく簡単な説明と利用例のみですが、変数・定数の基本的な知識や利用方法などをまとめてきました。
次は、変数・定数にまつわる重要な概念であるスコープについてまとめていきます。
スコープ
スコープとは変数、定数、関数、型などの有効範囲のことです。
スコープはその範囲に応じてグローバルスコープとローカルスコープに分けることができます。
同じスコープ内では名前は一意である必要があります。
では詳しく見ていきましょう。
ローカルスコープ
ローカルスコープとは関数や制御構文などによって定義されている、局所的なスコープのことです。
ローカルスコープ内で宣言された変数や定数などはそのスコープ内でのみ有効となり、スコープ外から参照することはできません。
func function() {
let a = "a in local scope"
print(a)
}
function() // functionを呼び出し
print(a) // functionのスコープ外からは参照できない
実行結果は以下のようになります。
グローバルスコープ
どのローカルスコープにも含まれていない(関数や型宣言などに含まれていない)スコープをグローバルスコープと言います。
グローバルスコープに宣言された変数や定数などは、ファイル外も含めてどこからでも参照することができます。
let a = "a in global scope"
func function() {
print(a) // functionのスコープ内からも参照できる
}
function() // functionを呼び出し
print(a) // functionのスコープ外からも参照できる
実行結果は以下のようになります。
スコープの有効範囲
ローカルスコープの説明の際、ローカルスコープで宣言されたものはスコープ外からは参照できないと書きました。
これは、内側にあるスコープ内で宣言されたものは参照できないという意味になります。
内側にあるスコープから外側のスコープを参照することはできます。(上の例でグローバルスコープの変数が、内側のスコープであるfuncton内から参照できていますよね)
ローカルスコープの中にローカルスコープがある場合も同じように、より内側のスコープからであれば外側のスコープで宣言されたものを参照することができます。
func function() {
let a = "a in function scope"
print(a) // functionのスコープ内からも参照できる
func local_function() {
let b = "b in local_function scope"
print(a) // より内側のlocal_functionから外側のfunction内のものは参照できる
print(b)
}
local_function()
print(b) // より外側のfunctionから内側のlocal_function内のものは参照できない
}
function() // functionを呼び出し
実行結果は以下のようになります。
スコープの優先順位
同一のスコープ内の場合、名前を一意にしなくてはなりませんが、異なるスコープであれば同一の名前を宣言できます。
その場合、名前を参照しているスコープから最も内側の参照可能なスコープで宣言されているものを参照します。
let a = "a in global scope"
func function() {
// グローバルスコープとは違うスコープなのでaを宣言可能
let a = "a in function scope" // 参照可能なaのうちより内側のfunctionのaを参照
print(a) //
func local_function() {
print(a) // 参照可能なaのうちより内側のfunctionのaを参照
}
local_function() // local_functionを呼び出し
}
function() // functionを呼び出し
print(a) // 参照可能なグローバルスコープのaを参照
実行結果は以下のようになります。
スコープは実際にプログラミングを行う上で重要な概念になります。
特にグローバルスコープはどこからでも参照できるため、思わぬところで参照される、値の再代入が行われてしまう、などバグの温床になりやすく注意する必要があります。
意図しない参照や再代入が行われないために必要最低限のスコープで宣言していくことが重要となります。
式
式とは?
式とはプログラムの処理を記述する基本的な要素のことで、値の変更や呼び出しなどを行います。
例えば、上の例で見てきた代入式も式の一種です。
他にも、処理のまとまりである関数を呼び出し処理を実行することも式です。
プログラミングは目的の達成のために正しい順序で式を組み立てていくこととも言えるでしょう。
Swiftにおいて、式で行うことは3つあります。
それぞれ具体的にみていきましょう。
値を呼び出す式
まずは値を呼び出している式です。
// 「1」という値を直接入力することで、Int型の「1」を呼び出している
var num: Int = 1 // = の右側の部分の「1」も式の一種である
他にも文字列を直接記述する「”string”」といった記述もString型の値を呼び出している式になります。
このように、値を直接記述して呼び出す式をリテラル式と言います。
// 変数に代入された値を呼び出している
var num: Int = 1
var sum: Int = num + 1 // numには「1」が代入されているので「1 + 1」となる。
num の部分のように変数に代入された値を呼び出す部分も式の一つです。
変数「sum」は「num」という変数の値を呼び出す式と、「1」というリテラル式の結果を加算した結果が代入されているということになります。
演算を行う式
式で行うこととして、ただ値を呼び出すだけでなく何かの値を求めるために演算を行うということがあります。
実は前のセクションの最後の式var sum: Int = num + 1
は値を呼び出している式であると同時に加算の算術演算を行なっている式でもあるのです。
式の中で行う演算には加減乗除の数値計算を行う算術演算や、与えられた式が正しいか間違っているかを判定する論理演算などの種類があります。
var sum: Int = 1 + 1 // 1と1を加算する算術演算を行い結果をsumに代入している
var bool: Bool = sum == 2 // sumが2と等しいかどうかを判定する論理演算を行い結果をboolに代入している
変数”bool”で指定している型「Bool」は真偽値を扱う型です。真偽値とは「真(True)」か「偽(False)」のみを値として扱い、論理演算の結果などに利用されます。
上記の例のように、式の中で演算は「+」(加算)や「==」(等しいかを判定)のようなそれぞれの演算に利用する特定の記述方法を用いて表現されます。
関数(処理のまとまり)を呼び出す式
関数とはある特定の処理をまとめていつでも呼び出せるようにしたものです。
関数については別の記事で詳しく取り上げたいと思いますが、式の中にはこの関数を呼び出すものもあります。
func function()-> Bool {
// function関数は以下2つの処理をまとめたもの
var sum: Int = 1 + 1 // sumに1+1の結果を代入
return sum == 2 // sumと2が等しいかの判定結果を関数の結果として返却
}
var bool: Bool = function() // function関数を呼び出し、返却された結果を変数"bool"に代入している
関数は同じ処理を複数箇所で行いたいときや煩雑になった処理をまとめるために使います。
上記の例のように定義した関数を呼び出すのも式で行うことの一つになります。
式のまとめ
上記の通り、式で行うことは値の呼び出し、演算、関数の呼び出しの3つあります。
プログラミングでは目的を達成するために、上記の3つを組み合わせて式を正しく記述していく必要があるのです。
まとめ
変数・定数、スコープ、式というプログラミングにおいて重要な基礎知識についてまとめました。
抽象的な話が多くなってしまいましたが、言葉の意味を理解しておくことで具体的にプログラムを学んで書いていく際に理解が深まると思うので、覚えておきましょう。
自分も改めて言葉の意味をまとめてみると、曖昧なまま認識している部分があると感じました。
しっかりと理解できるように今後もこういった記事を作成していければと思います。
最後までお読みいただきありがとうございました。
それでは、また。