【Swift】構造体

構造体とは値型と言われるもののひとつで変数や定数、関数をまとめて保持できるものです。
複数の変数や定数、関数をまとめて1つのオブジェクトとして保持し、汎用的に使用したい場合に使います。
作った構造体はインスタンス化することで使用することができるようになります。

前回は 関数 について書きました。

今回は 構造体 について書いていこうと思います。

構造体とは

構造体とは値型と言われるもののひとつで変数や定数、関数をまとめて保持できるものです。
複数の変数や定数、関数をまとめてひとつのオブジェクトとして保持し汎用的に使用したい場合に使います。
作った構造体は インスタンス化 することで使用することができるようになります。

構造体の概要

  • 複数のインスタンス間で値を共有せず、各インスタンスが値を保持する
  • 構造体の中に宣言された変数や定数を プロパティ という
  • 構造体の中に定義された関数を メソッド という
  • 構造体をインスタンス化する時に初めて値を決める場合が多いので、構造体のプロパティ定義時には初期値を決める必要はない(プロパティの宣言のみで良い)

インスタンス化とは

インスタンスとは 実体 という意味で、定義した構造体や class を元にプロパティに具体的な値を代入してインスタンス(実体)を作ります。これをインスタンス化と言います。
構造体や class をインスタンス化する時は、インスタンス化する時点でプロパティの初期値が決まってなければならないので、プロパティに初期値を入れるためには、 イニシャライザ で初期化することが必要となります。

イニシャライザとは

イニシャライザとは、構造体や class のプロパティを初期化( initialize )する特殊なメソッドのことです。他の言語でいうコンストラクタと同様。
型の整合性を保つためだったり、構造体や class のプロパティに値が無いままインスタンス化しようとしてエラーになるのを防ぐために必要となります。

※構造体と似ているものとして class が挙げられると思います。
書き方や見た目は似ていますが、
違いは構造体は 値型 であることに対して class は 参照型 であること、また、
値型 はインスタンス化する時、データ自体がコピーされて渡されるのに対して、
参照型 はインスタンス化する時、コピーではなく既存のデータが格納されている場所を参照するという所に違いがあります。
class についてはまた今度の記事で書こうと思います。

構造体とイニシャライザの書式

構造体の書式

struct 構造体名{
 プロパティ宣言
 イニシャライザ定義
 メソッド定義
 }

構造体は頭に struct キーワードを書い後に、構造体名を書きます。
中括弧 { } の中にプロパティイニシャライザメソッドを定義していきます。

イニシャライザの書式

init (引数名: 型名, ...){
     self.プロパティ名 = 値(値は引数のものでも良いし、引数同士を計算したものでも良い)
     (*全てのプロパティを初期化する)
     }
 }

イニシャライザは頭に init キーワードを付けます。
その後に ( ) を書いて中に 引数名 : 型名 をカンマ , で区切って必要な分書きます。
構造体をインスタンス化する時に、ここで書いた引数に初期値を入れることでインスタンス化することが出来ます。
中括弧 { } の中に初期化する処理を書いていきます。

構造体の定義例

struct Status{
    
    //プロパティ
    let name: String
    var hp: Int
    var mp: Int
    var attack: Int
    
    //イニシャライザ
    init(name:String, HP:Int, MP:Int, attack:Int) {
        self.name = name
        self.hp = HP
        self.mp = MP
        self.attack = attack
    }
    
    //メソッド
    func currentStatus() {
        print("\(name)のステータス")
        print("HP: \(hp)")
        print("MP: \(mp)")
        print("ちから: \(attack)")
    }

}

上のコードについて解説↓

構造体名

struct Status{
}

構造体の名前は Swift で推奨されているアッパーキャメルケースで書きます。
命名規則についてはこちらの記事で紹介しています。

プロパティ

struct Status{
    
    //プロパティ
    let name: String
    var hp: Int
    var mp: Int
    var attack: Int

}

構造体 Status には定数 1 つと変数 3 つの、計 4 つのプロパティを宣言していますが初期値は定義していません。後でインスタンス化するときに初期値を入れたいので宣言のみにしています。

イニシャライザ

struct Status{
    
    //プロパティ
    let name: String
    var hp: Int
    var mp: Int
    var attack: Int
    
    //イニシャライザ
    init(name:String, HP:Int, MP:Int, attack:Int) {
        self.name = name
        self.hp = HP
        self.mp = MP
        self.attack = attack
    }

}

( 引数名 : 型名 ) のところはプロパティの数だけ必要になる( プロパティ全ての初期化が完了しないとインスタンス化出来ません。)ので、引数を 4 つ書いています。
中括弧 { } の中に、引数から取った値を各プロパティに代入するという処理( 紐付け )を書いています。
self キーワードは構造体自身の事を指していて、まだインスタンス化されていないためプロパティを指す事ができません。 self. とする事で、自身のプロパティである事を明示しています。
※ 明らかに自身のプロパティであることが分かる状況であれば、self. は省略出来ます。

メンバーワイズイニシャライザ

メンバーワイズイニシャライザとはデフォルトで用意されているイニシャライザで、
単純または簡単なプロパティの初期化であれば、init関数 を書かなくても内部で暗黙的にイニシャライズされる機能です。
こっちの方が楽ですが、今回は init関数 を使ってイニシャライズして進めていきます。

メソッド

struct Status{
    
    //プロパティ
    let name: String
    var hp: Int
    var mp: Int
    var attack: Int
    
    //イニシャライザ
    init(name:String, HP:Int, MP:Int, attack:Int) {
        self.name = name
        self.hp = HP
        self.mp = MP
        self.attack = attack
    }
    
    //メソッド
    func currentStatus() {
        print("\(name)のステータス")
        print("HP: \(hp)")
        print("MP: \(mp)")
        print("ちから: \(attack)")
    }

}

インスタンス化したときのプロパティの初期値を確認したいので、現在の値を print() するメソッドです。
エスケープシーケンスを使って文字列の中に変数や定数を埋め込んでいます。

関数 についてはこちらの記事で紹介しています。

エスケープシーケンス についてはこちらの記事で紹介しています。

structコードimg

インスタンス化の書式

引数がない構造体の場合の書式

//構造体の名前の後に () を書きます

構造体名()

イニシャライザで引数を指定している場合の書式

//構造体の名前の後に () を書いて、中の引数に初期値を入力します

構造体名(イニシャライザで指定した引数, ...)

構造体をインスタンス化する例

struct Status{
    
    //プロパティ
    let name: String
    var hp: Int
    var mp: Int
    var attack: Int
    
    //イニシャライザ
    init(name:String, HP:Int, MP:Int, attack:Int) {
        self.name = name
        self.hp = HP
        self.mp = MP
        self.attack = attack
    }
    
    //メソッド
    func currentStatus() {
        print("\(name)のステータス")
        print("HP: \(hp)")
        print("MP: \(mp)")
        print("ちから: \(attack)")
    }

}

//構造体Statusをインスタンス化
var status = Status(name: "ゲレゲレ", HP: 100, MP: 30, attack: 90)

構造体のイニシャライザで設定した引数にそれぞれ値を入力して、変数 status に代入しています。
これで構造体 Status をインスタンス化することが出来たので、この 変数 status が構造体 Status のインスタンスとして使えるようになりました。

次は引数に入れた値がきちんと入っているか、インスタンスにアクセスして構造体の中で定義したメソッド currentStatus を呼んで実行してみます。

インスタンスにアクセスしてメソッドを呼ぶ方法

メソッドにアクセスするときの書式

//メソッドに引数がある場合
インスタンス名.メソッド名(引数名:値, ...)

//メソッドに引数がない場合
インスタンス名.メソッド名()

メソッドに引数がある場合はメソッド名の後に ( ) を書いて中に引数を入力。
インスタンス名 . メソッド名 ( 引数名 : 値 )

引数がないメソッドの場合はメソッド名の後に ( ) だけ書きます。
インスタンス名 . メソッド名 ( )

メソッドにアクセス

~ ~ ~
//構造体Statusをインスタンス化
var status = Status(name: "ゲレゲレ", HP: 100, MP: 30, attack: 90)

//メソッドにアクセス
status.currentStatus()

//実行結果
/*
ゲレゲレのステータス
HP: 100
MP: 30
ちから: 90
*/

メソッドを実行すると、インスタンス化時に引数に入れた値がきちんと構造体の各プロパティに代入されています。
プロパティである変数や定数にアクセスしたい場合もメソッド同様、
インスタンス名 . プロパティ名 とすることでアクセスすることが出来ます。

プロパティの値を変更する

プロパティの値を変更する関数を作って実行し、再度値の確認をしてみたいと思います。

~ ~ ~
//構造体Statusをインスタンス化
var status = Status(name: "ゲレゲレ", HP: 100, MP: 30, attack: 90)

//メソッドにアクセス
status.currentStatus()

//実行結果
/*
ゲレゲレのステータス
HP: 100
MP: 30
ちから: 90
*/

//プロパティの値を変更(更新)する関数
func levelUp(value: Int){
    status.hp += value
    status.mp += value
    status.attack += value
    
    var phrase = "\n\(status.name)はレベルが \(value) 上がった!\nHPが \(value) 上がった!\nMPが \(value) 上がった!\nちからが \(value) 上がった!\n"
    print(phrase)
}

引数を取る関数 levelUp を作ってみました。

処理の内容は、
関数で取った引数の値を、構造体の各プロパティに足します。その後、
引数の値を文字列に埋め込んで、変数 phrase に代入し print する、という処理にしています。

複合代入演算子 についてはこちらで紹介しています。

関数を実行してプロパティの値を変更してみます。

~ ~ ~
//インスタンス化
var status = Status(name: "ゲレゲレ", HP: 100, MP: 30, attack: 90)

//メソッドにアクセス
status.currentStatus()

//実行結果
/*
ゲレゲレのステータス
HP: 100
MP: 30
ちから: 90
*/

//プロパティの値を変更(更新)する関数
func levelUp(value: Int){
    status.hp += value
    status.mp += value
    status.attack += value
    
    var phrase = "\n\(status.name)はレベルが \(value) 上がった!\nHPが \(value) 上がった!\nMPが \(value) 上がった!\nちからが \(value) 上がった!\n"
    print(phrase)
}

//関数levelUpの引数に値を入力して実行
levelUp(value: 5)

//実行結果
/*
ゲレゲレはレベルが 5 上がった!
HPが 5 上がった!
MPが 5 上がった!
ちからが 5 上がった!
*/

上の例では関数の引数に 5 を入力して実行しています。
関数が実行されて、コンソールに実行結果が出力されたと思います。

最後に構造体のプロパティの値に変更が反映されているか、もう一度構造体のメソッドを呼んでみます。

~ ~ ~
//インスタンス化
var status = Status(name: "ゲレゲレ", HP: 100, MP: 30, attack: 90)

//メソッドにアクセス
status.currentStatus()

//実行結果
/*
ゲレゲレのステータス
HP: 100
MP: 30
ちから: 90
*/

//プロパティの値を変更(更新)する関数
func levelUp(value: Int){
    status.hp += value
    status.mp += value
    status.attack += value
    
    var phrase = "\n\(status.name)はレベルが \(value) 上がった!\nHPが \(value) 上がった!\nMPが \(value) 上がった!\nちからが \(value) 上がった!\n"
    print(phrase)
}

//関数levelUpの引数に値を入力して実行
levelUp(value: 5)

//実行結果
/*
ゲレゲレはレベルが 5 上がった!
HPが 5 上がった!
MPが 5 上がった!
ちからが 5 上がった!
*/

//プロパティに反映されているか確認
status.currentStatus()

//実行結果
/*
ゲレゲレのステータス
HP: 105
MP: 35
ちから: 95
*/

それぞれのプロパティに 5 ずつ足されています。
これで変更できました。

全コード

struct Status{
    
    //プロパティ
    let name: String
    var hp: Int
    var mp: Int
    var attack: Int
    
    //イニシャライザ
    init(name:String, HP:Int, MP:Int, attack:Int) {
        self.name = name
        self.hp = HP
        self.mp = MP
        self.attack = attack
    }
    
    //メソッド
    func currentStatus(){
        print("\(name)のステータス")
        print("HP: \(hp)")
        print("MP: \(mp)")
        print("ちから: \(attack)")
    }
}

//インスタンス化
var status = Status(name: "ゲレゲレ", HP: 100, MP: 30, attack: 90)

//メソッドにアクセスする
status.currentStatus()

//プロパティの値を変更(更新)する関数
func levelUp(value: Int){
    status.hp += value
    status.mp += value
    status.attack += value
    
    var phrase = "\n\(status.name)はレベルが \(value) 上がった!\nHPが \(value) 上がった!\nMPが \(value) 上がった!\nちからが \(value) 上がった!\n"
    print(phrase)
}

//関数levelUpの引数に値を入力して実行
levelUp(value: 5)

//プロパティに反映されているか確認
status.currentStatus()

//実行結果
/*
 ゲレゲレのステータス
 HP: 100
 MP: 30
 ちから: 90

 ゲレゲレはレベルが 5 上がった!
 HPが 5 上がった!
 MPが 5 上がった!
 ちからが 5 上がった!

 ゲレゲレのステータス
 HP: 105
 MP: 35
 ちから: 95
 */

お疲れ様でした。
以上 構造体 についてでした。

次回は 三項演算子 について書いていこうと思います。

実行環境

version
Xcode 14.2 (14C18)
Swift 5.2.4

公式ドキュメント

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/

【Swift】関数

関数とは処理をまとめて名前をつけたもので、入力を取って処理(演算)したり、任意のタイミングで同じ処理を再利用したりする事ができるものです。また、処理した値を出力することもできます。
引数と戻り値、返り値について
入力の事を引数、出力の事を戻り値、または返り値と言います。

前回は 配列型 について書きました。

今回は 関数 について書いていこうと思います。

関数とは

関数とは処理をまとめて名前をつけたもので、入力を取って処理(演算など)したり、任意のタイミングで呼び出して同じ処理を再利用する事ができるものです。また、処理した値を出力することもできます。

引数と戻り値(返り値)について

入力の事を引数、出力の事を戻り値、または返り値と言います。
関数に引数が必要ない場合、戻り値が必要ない場合は省略する事ができます。

関数の書式

引数が必要ない場合、戻り値が必要ない場合の書式

funk 関数名() {
     処理(ローカルスコープ)
 }

関数は頭に func キーワードを付けます。
関数名の後に ( ) だけ書いて、中括弧 { } の中に処理を書きます。

引数を取って戻り値を返したい場合の書式

funk 関数名(引数名:型名(入力の型),...) -> 戻り値(出力)の型名 {
     処理(ローカルスコープ)
     return 戻り値(出力)
 }

関数名を書いた後 ( ) を書いて、中に 引数名入力の型名 を書きます。
引数名型名 はコロン : で区切ります。
引数を複数書く場合は、カンマ , で区切ります。
矢印のような記号は、ハイフン と大なり > 記号になっていて、アロー演算子と言います。
アロー演算子 -> の後に 出力(戻り値)の型名 を書いて、 { } の中に処理を書きます。
処理の最後に return キーワードを書いて、出力(戻り値)の型 と同じ型の値を返します。

関数の書き方

引数が必要ない場合、戻り値が必要ない場合の例

//引数が必要ない場合、戻り値が必要ない場合の例
func greeting() {
    var a = "Hello.Swift!"
    print(a)
}

ただ文字列を出力するだけの関数で引数も戻り値も必要無いので、こういった場合は省略できます。

この関数を実行するときの例

//引数が必要ない場合、戻り値が必要ない場合の例
func greeting() {
    var a = "Hello.Swift!"
    print(a)
}
//実行例
greeting() //Hello.Swift!
functionコードimg2

引数を取って戻り値を返したい場合の例と実行例

//引数を取って戻り値を返したい場合の例
func calculation(a:Int, b:Int) -> Int {
    let result = a + b
    return result
}

この例は Int型 の 引数 a と、Int型の 引数 b を宣言して、 ab に入力された値を演算し、その結果を Int型 で返すというだけの関数です。
return で返したい戻り値の型と、 -> の戻り値の型名の所は同じ型でなければエラーになります。

この関数を実行するときの例

//引数を取って戻り値を返したい場合の例
func calculation(a:Int, b:Int) -> Int {
    let result = a + b
    return result
}

//実行例
var c = calculation(a: 1, b: 2)
print(c) //3

関数calculation の 引数 ab にそれぞれ 12 を入力して演算された結果を 変数 c に代入しています。
関数の処理の内容は a + b と足し算になっているので、1 + 2 の演算結果が 変数 c に代入されます。

数値型の演算 についてはこちらで紹介しています。

functionコードimg

この他に引数あり戻り値なしのパターンや、引数なし戻り値ありで書くこともできます。
引数がない関数はいつどこで呼び出そうと処理が同じなので汎用性は低いと思いますが、任意のタイミングで同じ処理を複数回したい場合などは、一度定義しておけば後は呼ぶだけなのでコード量も減らせて可読性も良くなると思います。
以上 関数 についてでした。

次回は 構造体 について書いていこうと思います。

実行環境

version
Xcode 14.2 (14C18)
Swift 5.2.4

公式ドキュメント

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/

【Swift】配列型

配列型とは、コレクション型の一種で複数のデータをまとめて並べたもののことを言います。
この配列に代入した値のことを要素と言い、この要素をインデックス番号という番号で管理します。
例外を除いて、配列に代入する要素は原則全て同じ型でなければなりません。

前回は スコープ について書きました。

今回は 配列型 について書いていこうと思います。

配列型とは

配列型 とは、コレクション型の一種で複数のデータをまとめて並べたもののことを言います。
この配列に代入した値のことを要素と言い、この要素インデックス番号という番号で管理します。
例外を除いて、配列に代入する要素は原則全て同じ型でなければなりません。

配列の書式

配列の型を明示した書式

//書式1
変数、定数名:Array<型名> = [要素, 要素, 要素, ...]

//書式2
変数、定数名:[型名] = [要素, 要素, 要素, ...]

要素全体は大括弧 [ ] で囲って、要素と要素はカンマ , で区切ります。

配列の型を明示しない書式( 型推論 )

//型推論
変数、定数名 = [要素, 要素, 要素, ...]

配列を使った例

//例1
var a:Array<Int> = [1, 2, 3, 4, 5]
print(type(of: a)) //Array<Int>
print(a) //[1, 2, 3, 4, 5]

//例2
var b:[Int] = [1, 2, 3, 4, 5]
print(type(of: b)) //Array<Int>
print(b) //[1, 2, 3, 4, 5]

//例3(型推論)
var c = [1, 2, 3, 4, 5]
print(type(of: c)) //Array<Int>
print(c) //[1, 2, 3, 4, 5]

上の例の 3 種類は書き方が少し違いますが、どれで書いても同じです。

この例は a , b , c という Int型 の配列にそれぞれ、[1,2,3,4,5] と 5 つの要素を代入している例です。

次に 配列a の要素にインデックス番号でアクセスしていきます。

インデックス番号

インデックス番号は 添え字 とも言います。
インデックス番号は最初の要素から順番に 0 , 1 , 2 と番号が振られていきます。 1 からではなく 0 から始まります。


要素にインデックス番号でアクセスする方法

//書き方例1
var a:Array<Int> = [1, 2, 3, 4, 5]
print(type(of: a)) //Array<Int>
print(a) //[1, 2, 3, 4, 5]

//書き方例2
var b:[Int] = [1, 2, 3, 4, 5]
print(type(of: b)) //Array<Int>
print(b) //[1, 2, 3, 4, 5]

//書き方例3(型推論)
var c = [1, 2, 3, 4, 5]
print(type(of: c)) //Array<Int>
print(c) //[1, 2, 3, 4, 5]

//インデックス番号でアクセス
print(a[0]) //1
print(b[0]) //1
print(c[0]) //1

配列名[インデックス番号] とすることで各要素にアクセスすることができます。
配列 a , b , c にはそれぞれ [1,2,3,4,5] と 5 つの要素が代入されています。
インデックス番号は 0 から始まるので 1 つ目の要素にアクセスするには、a[0] とすれば 配列a の 1 つ目の要素にアクセスできます。

Arrayコードimg

要素の結合と演算

String型 の配列であれば要素同士の結合や、数値型の配列であれば要素同士の演算をする事が出来ます。

文字列の要素を結合

//String型の要素を結合する例
var a:[String] = ["Hello.", "Swift!", "World!"]
print(type(of: a)) //Array<String>
print(a) //["Hello.", "Swift!", "World!"]

//結合
print(a[0] + a[1]) //Hello.Swift!
print(a[0] + a[2]) //Hello.World!

数値型の要素を演算

//数値型の要素を演算する例
var b:[Int] = [1, 2, 3]
print(type(of: b)) //Array<Int>
print(b) //[1, 2, 3]

//演算
print(b[0] + b[1]) //3
print(b[1] * b[2]) //6
Arrayコードimg2

多次元配列

多次元配列とは、配列の中に配列を入れ子することを言います。

多次元配列の書き方

//多次元配列の書き方例
var a:[[Int]] = [[1, 2, 3], [4, 5, 6]]
print(type(of: a)) //Array<Array<Int>>
print(a) //[[1, 2, 3], [4, 5, 6]]

配列の中に複数の配列が格納されています。
次はこの多次元配列の要素にアクセスしてみます。

多次元配列のインデックス番号

多次元配列の要素にインデックス番号でアクセスしてみる。

//多次元配列の書き方例
var a:[[Int]] = [[1, 2, 3], [4, 5, 6]]
print(type(of: a)) //Array<Array<Int>>
print(a) //[[1, 2, 3], [4, 5, 6]]

//多次元配列の要素にインデックス番号でアクセス
print(a[0][1]) //2

上の例だと [1,2,3] は 0 番目の配列で [4,5,6] は 1 番目の配列ということになります。したがって a [0][1]配列a の 0 番目の配列の 1 番目の要素ということになるので、 2 が出力されます。

Arrayコードimg3

以上 配列型 についてでした。

次回は 関数 について書いていこうと思います。

実行環境

version
Xcode 14.2 (14C18)
Swift 5.2.4

公式ドキュメント

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/

【Swift】スコープ

スコープとは変数や定数が有効な範囲のことを言います。
スコープには ローカルスコープ と グローバルスコープ があります。
それぞれの特徴を見ていきましょう。ローカルスコープは中括弧 {} の中を指す。
グローバルスコープはどのローカルスコープにも属さないスコープを指す。

前回は ネスト について書きました。

今回は スコープ について書いていこうと思います。

スコープとは

スコープとは変数や定数が有効な範囲のことを言います。
スコープには ローカルスコープ グローバルスコープ があります。
それぞれの特徴を見ていきましょう。

ローカルスコープの特徴

  • ローカルスコープは中括弧 { } の中を指す
  • ローカルスコープ内に宣言した変数や定数は、ローカル変数またはローカル定数と言う
  • ローカルスコープ内に宣言された変数や定数は、中括弧 { }中でしか使えない(ローカルスコープを抜けると破棄されるため)
//ローカルスコープ例
for _ in 0 ... 9 {
    var a = 1 //ローカル変数
    print(a)
}

//実行結果
/*
1
1
1
1
1
1
1
1
1
1
 */

上の例はローカルスコープ内に変数を定義して、同じスコープ内から print関数 でアクセスしている例です。
ローカル変数にアクセスするには同じスコープ内からじゃないとアクセスできません。

for _ in 0 ... 9 {
    var a = 1 //ローカル変数
}
print(a) //これはエラーになります。


このようにローカルスコープの外から、ローカルスコープ内の変数や定数にアクセスしようとするとエラーになります。

scopeコードimg

グローバルスコープの特徴

  • グローバルスコープはどのローカルスコープにも属さないスコープを指す
  • どのローカルスコープにも属さない変数や定数は、グローバル変数またはグローバル定数と言う
  • グローバルスコープは同じプロジェクト内であればどのファイルからでもアクセス可能
var b = 1

for _ in 0 ... 9 {
    print(b)
}

//実行結果
/*
1
1
1
1
1
1
1
1
1
1
 */

上の例はローカルスコープの外に 変数 b を宣言して、ローカルスコープの中から print関数 でアクセスしている例です。
変数 b は中括弧 { } の外で宣言しているので、グローバルスコープ(グローバル変数)となりどこからでもアクセスできます。

scopeコードimg2

グローバル変数や定数はどこからでもアクセスできて使いやすいメリットもありますが、長いプログラムになってくると変数や定数も増えてきて見づらくなってきます。
ローカルスコープ内でしか使わない変数や定数はできるだけローカルスコープ内に書いた方が、可読性の向上やエラーの回避につながると思います。

scopeコードimg3

以上 スコープ についてでした。

次回は 配列型 について書いていこうと思います。

実行環境

version
Xcode 14.2 (14C18)
Swift 5.2.4

公式ドキュメント

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/

【Swift】ネスト

ネストとは”入れ子”という意味で、ネスティングとも言います。
例えばfor文の中にfor文、if文の中にif文、for文の中にif文などを入れ子することをネストすると言います。

if文についてはこちらで紹介しています。

for文についてはこちらで紹介しています。

前回は 複合代入演算子 について書きました。

今回は ネスト について書いていこうと思います。

ネストとは

ネストとは”入れ子”という意味で、ネスティングとも言います。
例えば for文 の中に for文if文 の中に if文for文 の中に if文 などを入れ子することをネストすると言います。

if文 についてはこちらで紹介しています。

for文 についてはこちらで紹介しています。

for文の中にfor文

for文 の中に for文 をネストする例

//for文の中にfor文をネスト
for i in 0 ... 2 {
    for j in 0 ... 2 {
        print(i, j) //iとjに代入されている値をprintするだけの処理
    }
}

//実行結果
/*
0 0
0 1
0 2
1 0
1 1
1 2
2 0
2 1
2 2
 */


ij に代入されている値を print するだけの処理です。
は終了値を含む範囲演算子なので上の例だと最初の for文 も中の for文 も、 0,1,2 と、3 回繰り返します。

範囲演算子 についてはこちらで紹介しています。

※コードが流れていく順番
最初 for文i0 が代入されて中の for文 に進む

中の for文 が、0,1,2 と 3 回処理が繰り返される

最初の for文 に戻って次は 1 が代入されて中の for文 に進む

また中の for文 が、0,1,2 と 3 回処理が繰り返される

最初の for文 に戻って次は 2 が代入されて中の for文 に進む

また中の for文 が、0,1,2 と 3 回処理が繰り返される

最初の for文3 回目まで繰り返したので for文 から抜ける
という順番でコードが流れていきます。

nestコードimg

for文の中にif文

for文 の中に if文 をネストする例

//for文の中にif文をネスト
for i in 1 ... 10 {
    if i % 2 == 0 {
        print(i)
    }
}

//実行結果
/*
2
4
6
8
10
 */

for文 を 10 回繰り返して、もし i の値が偶数の値だった場合に printi の値を出力するというコードです。

if文 の条件式は i%2==0 となっています。
これは、もし i の値を 2 で割った余りが 0 だったら true なので、i の値を print で出力します。
余りが 0 じゃないということは奇数なので false となり、その場合 if文 はスキップされます。
==!= に変えると奇数のみの出力になります。

nestコードimg2


あまり多重にネストするとエラーの原因や、思った通りの処理にならなかったり可読性も下がりそうなので、使う時はよく考えて注意しながら使う必要がありそうです。
以上 ネスト についてでした。

次回は スコープ について書いていこうと思います。

実行環境

version
Xcode 14.2 (14C18)
Swift 5.2.4

公式ドキュメント

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/

【Swift】複合代入演算子

複合代入演算子とは、前の記事で紹介した算術演算子と代入を組み合わせた演算子のことを言います。
複合代入演算子を使うとコードを簡潔にできたり、読みやすくなります。
インクリメントやデクリメントなんかにも使われてるのをよく見かけます。
まず複合代入演算子の前に算術演算子について理解しておきましょう。

前回は for文と範囲演算子 について書きました。

今回は 複合代入演算子 について書いていこうと思います。

複合代入演算子とは

複合代入演算子とは、前の記事で紹介した算術演算子と代入を組み合わせた演算子のことを言います。
複合代入演算子を使うとコードを簡潔にできたり、読みやすくなります。
インクリメントやデクリメントなんかにも使われてるのをよく見かけます。
まず複合代入演算子の前に算術演算子について理解しておきましょう。

算術演算子 についてはこちらで紹介しています。

では複合代入演算子の種類を見ていきましょう。

複合代入演算子の種類

演算子意味
+=足し算(加算)と代入
-=引き算(減算)と代入
*=掛け算(乗算)と代入
/=割り算(除算)と代入
%=割り算の余り(剰余)と代入

演算例

複合代入演算子を使った演算例と、使わなかった場合の例

+= (加算と代入)

// +=
var a = 1
a += 1
print(a) //2

//複合代入演算子を使わなかった場合
a = a + 1

-= (減算と代入)

// -=
var b = 2
b -= 1
print(b) //1

//複合代入演算子を使わなかった場合
b = b - 1

*= (乗算と代入)

// *=
var c = 2
c *= 2
print(c) //4

//複合代入演算子を使わなかった場合
c = c * 2

/= (除算と代入)

// /=
var d = 4
d /= 2
print(d) //2

//複合代入演算子を使わなかった場合
d = d / 2

%= (剰余と代入)

// %=
var e = 5
e %= 2
print(e) //1

//複合代入演算子を使わなかった場合
e = e % 2
+=コードimg

ちょっとですが簡潔になり可読性も良くなったと思います。
以上 複合代入演算子 でした。

次回は ネスト について書いていこうと思います。

実行環境

version
Xcode 14.2 (14C18)
Swift 5.2.4

公式ドキュメント

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/

【Swift】for文と範囲演算子

for文とは繰り返し構文のことで、for-in文とも言います。
指定した回数分の処理を繰り返す事ができる構文です。同じ処理を複数回ループさせたい時に使います。
範囲演算子とはfor文と一緒に使うことが多い演算子で、開始値から終了値までの範囲を決めるときに使います。
まずはよく使う範囲演算子からみていきましょう。

前回は if文 と if-else文 について記事を書きました。

今回は for文 と範囲演算子について書いていこうと思います。

for文と範囲演算子とは

for文 とは繰り返し構文のことで、for-in文 とも言います。
指定した回数分の処理を繰り返す事ができる構文です。同じ処理を複数回ループさせたい時に使います。
範囲演算子とは for文 と一緒に使うことが多い演算子で、開始値から終了値までの範囲を決めるときに使います。
まずはよく使う範囲演算子からみていきましょう。

範囲演算子の種類

範囲演算子意味
終了値を含む
..<終了値を含まない

この 2 種類がよく使われる範囲演算子だと思います。

for文の書式

for 定数名 in 整数A 範囲演算子 整数B {
 繰り返したい処理
 }

for文 は頭に for キーワードを付けます。
定数名は何でもいいですが、基本 ij とすることが多いと思います。
整数 A より、整数 B の方が大きい整数でなければエラーになります。

for文 の書き方

//for文の書き方例1
for i in 1 ... 10 {
    print(i)
}

この例は print( i ) を 10 回ループさせる例です。
範囲演算子の は、終了値を含む演算子なので 1 ~ 10 回目までループします。

※コードの流れ
i には最初 1 が代入される

print( i ) を実行

for文 の閉じかっこ } まで処理が来たら一度破棄される

戻って次は i2 が代入される

また print( i ) を実行、、、
という流れで回数分コードが読まれていきます。

//for文の書き方例2
for i in 1 ..< 10 {
    print(i)
}

この例は上の例 1 と似ていますが、範囲演算子が から ..< に変わっています。
この ..<終了値を含まない演算子なので、ループする回数は 1 ~ 9 回目までとなります。

for-inコードimg

Int型 の変数や定数であれば、範囲の所を a ba ..< b のような書き方も出来ます。

var a = 1
var b = 10

for i in a ... b {
    print("\(i)回目")
}

for i in a ..< b {
    print("\(i)回目")
}
for-inコードimg2

インクリメントとデクリメント

インクリメントとは、何かの数字に 1 足すことをインクリメントと言います。
デクリメントはその逆で、何かの数字から 1 引くことをデクリメントと言います。

例えば 1 を 10 回インクリメントしたい時、for文 を使わず書くとこうなります。

var a = 0
a = a + 1
a = a + 1
a = a + 1
a = a + 1
a = a + 1
a = a + 1
a = a + 1
a = a + 1
a = a + 1
a = a + 1
print(a) //10

1 行 1 行インクリメントしていかないと 10 回足せません。
これを for文 で書きます。

var a = 0

for _ in 1 ... 10 {
    a = a + 1
}
print(a) //10

結果は同じで、コードが短くなりました。可読性も向上したと思います。

for文 の定数名の所がアンダーバー _ になっていますが、これは for文 の中の処理で使わない場合に、アンダーバー _ として省略になっています。
以上 for文 と 範囲演算子 についてでした。

次回は 複合代入演算子 について書いていこうと思います。

実行環境

version
Xcode 14.2 (14C18)
Swift 5.2.4

公式ドキュメント

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/

【Swift】if文とif-else文

if文とは、条件式によって処理を分岐したい場合に使う構文で、もし〇〇だったらこの処理、もし〇〇じゃなかったら別の処理、どっちにも当てはまらない場合はこの処理、のように処理を分岐させたい場合に使う構文です。
条件式がtrueであれば、if文の処理が実行されて、falseであればそのif文の処理はスキップされます。

前回は 論理演算子 について記事を書きました。

今回は if文 と if-else文 について書いていこうと思います。

if文とは

if文 とは、条件式によって処理を分岐したい場合に使う構文で、もし〇〇だったらこの処理、もし〇〇じゃなかったら別の処理、どっちにも当てはまらない場合はこの処理、のように処理を分岐させたい場合に使う構文です。
条件式が true であれば、if文 の処理が実行されて、false であればその if文 の処理はスキップされます。

if文の書式

if文 は、もしそうであれば( Bool値true であれば )この処理を実行します。という構文です。
Bool値false だった場合 if文 はスキップされます。

 if Bool値、または条件式 {
     Bool値、条件式の結果がtrueであればこの中の処理が実行される
     trueでなければこのif文はスキップされる
 }

if文 は頭に、if キーワードを付けます。

if文のを使った例

//if文の書き方例
var a:Bool = true
var b:Bool = false

if a {
    print("あいうえお") //aはtrueなのでこのif文の処理が実行されます
}

if b {
    print("かきくけこ") //bはfalseなのでこのif文はスキップされます
}
if-elseコードimg

比較演算子を使った if文

書式

var a = 1
var b = 2

if a > b {
    aとbの条件式の結果がtrueであればここの処理が実行されます
}

比較演算子 についてはこちらの記事で紹介しています。

比較演算子を使った if文 の例

//比較演算子を使ったif文の例
var HP:Int = 30 //好きな整数を代入してください

//もしHPが80より大きかったらこのif文は実行されます(80は含まれない)
if HP > 80 {
    print("ガンガンいこうぜ")
}

//もしHPが60以上であればこのif文は実行されます(60も含まれる)
if HP >= 60 {
    print("じゅもんつかうな")
}

//もしHPが30以下であればこのif文は実行されます(30も含まれる)
if HP <= 30 {
    print("いのちだいじに")
}

Int型変数HP には 30 が代入されています。
1 つ目の if文 の条件は HP80 より大きかったら実行されます。( 80 は含まれない )
2 つ目の if文 の条件は HP60 以上であれば実行されます。( 60 も含まれる )
3 つ目の if文 の条件は HP30 以下であれば実行されます。( 30 も含まれる )
変数HP の値には 30 が代入されているので、当てはまっている 3 つ目( 1 番下 )の if文 のみ実行されて、他 2 つの if文 はスキップされます。

if-elseコードimg

if-else文

if-else文 は、if文Bool値 、または条件式が false だった場合 if文 の処理はスキップして、else文 の処理を実行するという構文です。

if-else文 の書式

if Bool値、または条件式 {
    Bool値、または条件式がtrueであればここの処理が実行されます
} else {
    Bool値、または条件式がfalseであればここの処理が実行されます
}

else文 は、else キーワードを書いて中括弧 { } の中に処理を書きます。

if-else文 を使った例

//if-else文の書き方例
var a:Bool = false

if a { //aがtrueであればこのif文の処理が実行されます
    print("aの値はtrueです")
} else { //aがtrueでなければこのelse文の処理が実行されます
    print("aの値はfalseです")
}
if-elseコードimg3

比較演算子を使った if-else文

書式

var a = 1
var b = 2

if a > b {
    aとbの条件式がtrueであればここの処理が実行されます
} else {
    aとbの条件式がfalseであればここの処理が実行されます
}

比較演算子 についてはこちらの記事で紹介しています。

比較演算子を使った if-else文 の例

//比較演算子を使ったif-else文の例
var point:Int = 99 //好きな整数を代入してください

//もしpointの値が100以上であればこのif文が実行されます
if point >= 100 {
    print("レベルが1上がった!")
//そうでなかったら(pointの値が99以下だったら)このelse文が実行されます
} else {
    print("\(point)の経験値をかくとく!")
}

Int型変数point には 99 が代入されています。
point の値が 100 以上であれば true になり、if文 の処理が実行されます。
99 以下であれば false になるので、else文 の処理が実行されます。
上の例では print(\(point)の経験値をかくとく!”) が実行されます。

if-elseコードimg5

point の値を 100 以上に変えると if文 の条件式は true になるので、
if文print(“レベルが1上がった!”) が実行されます。

else-if

分岐を増やしたい場面もよく出てくると思います。
そんな時は else-if を使うことで分岐を増やすことが出来ます。
if文 の後に else if キーワードを書いて その後に条件式を書き、{ } の中に処理を書きます。

書式

var a = 1
var b = 2

if a > b {
    aとbの条件式がtrueであればここの処理が実行されます
} else if a < b {
    上の条件式がfalseであれば、次にこのelse-if文が判定され、もしtrueであればここの処理が実行されます
} else {
    上の条件式がどれもfalseであればここの処理が実行されます
}

else-if で分岐を増やす例

//else-ifで分岐を増やす例
var jp = 3
var us = 2

if jp > us { //jpの値がusより大きかったら
    print("Japan Winner!")
    
} else if jp < us { //jpの値がusより小さかったら
    print("USA Winner!")
    
} else { //上の条件式がどれもfalseであれば
    print("Draw!")
}

まず最初の if文 の条件式が判定されて、false であれば次の else-if文 の条件式が判定されます。そして else-if文 の条件式も false だった場合に else文 が実行されるという流れになります。

jp の値が us の値より大きければ print(“Japan Winner!”)
jp の値が us の値より小さければ print(“USA Winner!”)
上の 2 つの条件式が false つまり同じ値であれば print(“Draw!”)
が実行されます。

上記の例では 変数 jp3変数us2 が代入されています。
最初の if文 の条件式で true になるので print(“Japan Winner!”) が実行されます。

if-elseコードimg4

これで分岐を増やす事ができましたが、分岐の数が 3 つや 4 つ、またはそれ以上になってくるととても読みづらくなってきます。そういう場合は if文 とは別に Switch文 という条件分岐出来る構文があるので、そっちの方がいい場合もあります。
Switch文 についてはまた今度書こうと思います。

比較演算子と論理演算子を使った if文

書式

var a = 1
var b = 2
var c = 3

//&&(and、かつ)
if a < b && b < c {
   aがbより小さい かつ bがcより小さい場合にここの処理が実行される
}

//||(or、または)
if a > b || a < c {
    aがbより大きい または aがcより小さい場合にここの処理が実行される
}

&& (and、かつ)演算子は、左辺と右辺の値がどっちも true の時のみ実行されます。
|| (or、または)演算子は、左辺と右辺の値どちらかが true であれば実行されます。

比較演算子 についてはこちらの記事で紹介しています。

論理演算子 についてはこちらの記事で紹介しています。

比較演算子と論理演算子を使った if文 の例

//比較演算子と論理演算子を使ったif文の例
var kokugo = 60
var eigo = 80

//&&
if kokugo >= 80 && eigo >= 80 { //kokugoが80以上かつ、eigoが80以上であればここの処理が実行されます
    print("合格!")
} else { //上の条件から外れた場合はここの処理が実行されます
    print("不合格!")
}

//||
if kokugo >= 80 || eigo >= 80 { //kokugoが80以上または、eigoが80以上であればここの処理が実行されます
    print("合格!")
} else { //上の条件から外れた場合はここの処理が実行されます
    print("不合格!")
}

変数kokugo60eigo80 が代入されています。


上の if文 は、kokugo の値が 80 以上かつ、eigo の値が 80 以上であれば実行されます。
&& は左辺と右辺の両方の値が true でなければ実行されないので、この if文 はスキップされて、else文 が実行されます。

下の if文 は、kokugo の値が 80 以上または、eigo の値が 80 以上であれば実行されます。
|| は左辺と右辺どちらかが true であれば実行されるので、この if文 の処理が実行されて、else文 はスキップされます。

if-elseコードimg6

以上 if文 と if-else文 についてでした。結構よく使う構文なので押さえておきたいポイントだと思います。

次回は for文 について書いていこうと思います。

実行環境

version
Xcode 14.2 (14C18)
Swift 5.2.4

公式ドキュメント

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/

【Swift】論理演算子

前回の記事で真理値型と比較演算子について書きましたが、論理演算子も条件分岐をして処理を分ける時などによく使われる演算子で、比較演算子とセットで使うこともあります。比較した値はBool値で返ってきます。
まずは論理演算子の種類を見ていきましょう。

前回は 真理値型と比較演算子 について記事を書きました。

今回は 論理演算子 について書いていこうと思います。

論理演算子とは

前回の記事で真理値型と比較演算子について書きましたが、論理演算子も条件分岐をして処理を分ける時などによく使われる演算子で、比較演算子とセットで使うこともあります。比較した値は Bool値 で返ってきます。Bool型 についてはこちらの記事で紹介しています。

まずは論理演算子の種類を見ていきましょう

論理演算子の種類

各論理演算子の true になる場合と false になる場合をまとめてみました。

|| は shiftキー を押しながら ¥マーク 2 回。(Mac)
論理演算値truefalse
&&true && truetrue && false
false && true
false && false
||true || true
true || false
false || true
false || false
!! false! true

論理演算子を使った例

&& (and)

&& は、〜かつ〜 という意味で、論理積とも言います。左辺と右辺の値がどっちも true であれば true、どちらかが false、または両方 false であれば false になる演算子です。

//定数a,b,cにそれぞれtrueかfalseを代入
let a = true
let b = false
let c = true
var d:Bool

//&&
d = a && b //false
d = a && c //true

&&
左辺と右辺がどっちも true の場合のみ true になる演算子なので a && bfalse で、a && ctrue という結果になります。

|| (or)

|| は、〜または〜 という意味で、論理和とも言います。左辺と右辺どちらかが true であれば true、両方 false の場合のみ false になる演算子です。

//定数a,b,cにそれぞれtrueかfalseを代入
let a = true
let b = false
let c = true
var d:Bool

//||
d = a || b
print(d) //true
d = a || c
print(d) //true
d = b || b
print(d) //false

||
左辺か右辺の値がどちらかでも true であれば true になる演算子なので、b || bfalse、それ以外は true という結果になります。

! (not)

! は、〜でない という意味で、否定とも言います。Bool値の前に ! を付けることで、true を false に、false を true に変える事ができる演算子です。

//定数a,b,cにそれぞれtrueかfalseを代入
let a = true
let b = false
let c = true
var d:Bool

//!
d = !a
print(d) //false
d = !b
print(d) //true

!
a に入っている値は true ですが、! a とすると false に変わっています。

logical-operatorコードimg

以上 論理演算子 についてでした。
結構よく使うので押さえておきたいポイントだと思います。

次回は if文 について書いていこうと思います。

実行環境

version
Xcode 14.2 (14C18)
Swift 5.2.4

公式ドキュメント

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/

【Swift】真理値型と比較演算子

前回は文字列型と文字列の型変換について記事を書きました。今回は真理値型と比較演算子について書いていこうと思います。
真理値型は真偽値型やBool型とも言われていて、真を表すtrueか偽を表すfalseかのどちらかの値をとる事が出来る型です。

前回は 文字列型と文字列の型変換 について記事を書きました。

今回は 真理値型と比較演算子 について書いていこうと思います。

真理値型とは

真理値型は、真偽値型や Bool型 とも言われていてを表す true か、を表す false かのどちらかの値をとる事が出来る型です。
プログラムの中で、ある条件や命題によって分岐して処理を分けたい時などに欠かせない型です。比較演算子と組み合わせて使うことで、例えばボタンの on/off 切り替えだったり、この条件であればこの処理、この条件でなければ別の処理、みたいな使い方も出来ます。まずは比較演算子の種類を見ていきましょう。

比較演算子の種類

a の値と b の値を比較した時の例

比較演算子truefalse
>a > ba が b より大きいa が b より小さい
<a < ba が b より小さいa が b より大きい
>=a >= ba が b 以上a が b 以下
<=a <= ba が b 以下a が b 以上
==a == ba が b と等しいa が b と等しくない
!=a != ba が b と等しくないa が b と等しい

上記の条件によって truefalse の値が返ってきます。

Bool型の宣言例と比較演算子を使った例

Bool型 の宣言と比較演算子を使って比較してみます。

> (大なり)

//Bool型の宣言例
var trueOrFalse:Bool
print(type(of: trueOrFalse)) //Bool

var a = 1
var b = 2

// >
trueOrFalse = a > b
print(trueOrFalse) //false

a > b
ab より大きければ true、ab より小さければ false になります。この場合は ab より小さいので結果は false になります。

< (小なり)

var trueOrFalse:Bool
print(type(of: trueOrFalse)) //Bool

var a = 1
var b = 2

// <
trueOrFalse = a < b
print(trueOrFalse) //true

a < b
ab より小さければ true、ab より大きければ false になります。この場合は ab より小さいので結果は true になります。

>= (大なりイコール)

var trueOrFalse:Bool
print(type(of: trueOrFalse)) //Bool

var a = 1
var b = 2

// >=
trueOrFalse = a >= b
print(trueOrFalse) //false

a >= b
ab 以上だったら true、ab 以下だったら false になります。この場合は ab 以下なので結果は false になります。

<= (小なりイコール)

var trueOrFalse:Bool
print(type(of: trueOrFalse)) //Bool

var a = 1
var b = 2

// <=
trueOrFalse = a <= b
print(trueOrFalse) //true

a <= b
ab 以下だったら true、ab 以上だったら false になります。この場合は ab 以下なので結果は true になります。

== (イコール)

var trueOrFalse:Bool
print(type(of: trueOrFalse)) //Bool

var a = 1
var b = 2

// ==
trueOrFalse = a == b
print(trueOrFalse) //false

a == b
ab と等しかったら true、ab と等しくなかったら false になります。この場合は ab と等しくないので結果は false になります。

!= (ノットイコール)

var trueOrFalse:Bool
print(type(of: trueOrFalse)) //Bool

var a = 1
var b = 2

// !=
trueOrFalse = a != b
print(trueOrFalse) //true

a != b
ab と等しくなかったら true、ab と等しかったら false になります。この場合は ab と等しくないので結果は true になります。

Boolコードimg

以上の 6 種類がよく使われる 比較演算子 かと思います。

次回は 論理演算子 について書いていこうと思います。

実行環境

version
Xcode 14.2 (14C18)
Swift 5.2.4

公式ドキュメント

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/