Swift プロトコル、パート1

プロトコルの基本

プロトコルの定義方法

構造体・クラス・列挙型などの型がプロトコルAに準拠するとプロトコルAの持つ機能・特性を準拠した型も持つことができます。

プロトコルAに準拠する方法

複数のプロトコルに準拠した型を定義する場合は上記のように,(カンマ)で区切って記述します。

上記のように記述したうえで、準拠するプロトコルが要求するプロパティ・メソッドなどを型の中で実装すれば、プロトコルに準拠した型を定義できます。

sample1

protocol ProtocolA{
    func methA()
}

struct StructA:ProtocolA{
    func methA(){
        
    }
}

sample1ではProtocolAという名のプロトコルを定義し、次にProtocolAに準拠した構造体StructAを定義しています。

ProtocolAは、準拠する型(StructA)に、メソッドmethA()の実装を要求していますので、StructAの定義内でメソッドmethA()を定義する必要があります。

プロトコルが要求するプロパティ・メソッドを準拠する型内で定義していないとコンパイルエラーとなります。(sample2)

sample2

protocol ProtocolA{
    func methA()
    func methB()
}

struct StructA:ProtocolA{
    func methA(){
        
    }
}
main.swift:7:8: error: type 'StructA' does 

Swiftの基本 イニシャライザ、パート2

パート1でイニシャライザの定義、挙動を見ました。そこで次のサンプル(sample1)

sample1

struct Sample{
    let prop1:Int    //構造体定義時にプロパティを初期化していない
    let prop2:String
    let prop3:String
    //イニシャライザを定義していない
}

let sample1=Sample(prop1:10,prop2:"wow",prop3:"good")

print(sample1.prop1)
print(sample1.prop2)
print(sample1.prop3)
10
wow
good

構造体Sample型に定義されているのは

prop1(Int型)

prop2(String型)

prop3(String型)

のみで、イニシャライザは定義されていません。さらに構造体Sample定義時にプロパティを初期化していません。しかし実際実行すると期待通りに結果が出力され、エラーは出ません。つまりイニシャライザを定義していないが、すべてのプロパティが初期化されています。


構造体の場合、イニシャライザを自分で定義しない場合、自動的にメンバワイズイニシャライザ(memberwise initializer)が内部的に用意されます。

メンバワイズイニシャライザは、型が持つすべてのストアドプロパティを引数に持つイニシャライザで、上記の例だと、

init(prop1:Int,prop2:String,prop3:String){
    self.prop1=prop1
    self.prop2=prop2
    self.prop3=prop3
}

このようなイニシャライザを定義したのと同じ状態(実際には定義していない)になります。

ということで、sample1を見ると一見エラーが出そうですが、実際エラーは出ずにすべてのプロパティが初期化されている、ということですね。

Swiftの基本 イニシャライザ、パート1

1.イニシャライザの基本

まずストアドプロパティtoとコンピューテドプロパティbodyを持つ構造体Greetを定義します。(sample1)

sample1

struct Greet{
    let to:String
    var body:String{
        return "Hello,\(to)!!!!!"
    }
    
    init(to:String){  //←がイニシャライザ
        self.to=to
    }
}

init(引数){初期化処理}

の部分がイニシャライザの定義。

次に構造体Greetのインスタンスを生成します。(sample2)

sample2

struct Greet{
    let to:String
    var body:String{
        return "Hello,\(to)!!!!!"
    }
    
    init(to:String){
        self.to=to
    }
}

let gr1=Greet(to:"address1")  //インスタンス生成。この時自動的に
                              //イニシャライザが実行される。

print(gr1.body)
Hello,address1!!!!!