SwiftUI - protocolとextensionについて

1. protocolの書き方

プロトコルは、特定のタスクまたは機能の一部を合わせメソッド、プロパティ、およびその他の要件の設定(ルール)を定義する。protocol プロトコル名 {...}の中に設定したい内容を記述します。letではなくvarじゃないとエラーになります。変数名: 型の後に、{get}もしくは、{get set}を設定します。(get - 読み取り、set - 書き込み)

protocol SomeProtocol {
    //var 変数名: 型 {get} or {get set}
}

構造体にプロトコルを定義する場合

struct SomeStructure: Protocol1, Protocol2 {
    //...
}

クラスにスーパークラスがある場合

class SomeClass: SomeSuperclass, Protocol1, Protocol2 {
    //...
}

2. protocolの使い方

下記は、試しに書いてみたものです。プロトコルの{get}{get set}の違いは、下記のように後から値の追加ができるということのようです。

protocol Body {
  var height: Double {get}
  var grow: Double {get set}
}

struct Human: Body {
  var height: Double = 0.0
  var grow: Double {
    get {
      height * 1.02
    }
    set {
      height += newValue
    }
  }
}
var boy = Human()

boy.height = 140.0

print(round(boy.grow * 10)/10) 
//140 * 1.02 = 142.8

boy.grow = 2.0 //newValueに値を入れる

print(round(boy.grow * 10)/10) 
//(140 * 1.02) + 2.00 = 144.8

3. extensionの書き方

extensionは、既存のクラス、構造、列挙、またはプロトコルタイプに新しい機能を追加できます。

extension SomeType {
    //...
}

プロトコルと一緒に使う場合

extension SomeType: Protocol1, Protocol2 {
    //...
}

4. extensionの使い方

下記は、swiftドキュメントに記載してあったDouble型のextensionの例です。Double型の拡張なのでInt型などには使えません。

extension Double {
  var km: Double { return self * 1_000.0 }
  var m: Double { return self }
  var cm: Double { return self / 100.0 }
  var mm: Double { return self / 1_000.0 }
}

print("1kmは\(1.0.km)m") //1kmは1000.0m
print("1mは\(1.0.m)m") //1mは1.0m
print("1cmは\(1.0.cm)m") //1cmは0.01m
print("1mmは\(1.0.mm)m") //1mmは0.001m

//var test:Int = 1
//print(test.km) << エラーになります

5. extensionを作成してみる

extensionを作成してみようと思います。下記のようにZStack {Color(...) xxx}で囲うと画面全体の背景に色を設定できます。この部分をextension化してみます。

struct ContentView: View {
  var body: some View {
    ZStack {
      Color(red: 0.2, green: 0.4, blue: 0.9, opacity: 1)
        .edgesIgnoringSafeArea(.all)
      VStack {
        Text("Hello, World!")
      }
    }
  }
}

下記のように記述するとViewextensionとして使えるようになります。

extension View {
  func ZSC() -> some View {
    ZStack {
      Color(red: 0.2, green: 0.4, blue: 0.9, opacity: 1)
        .edgesIgnoringSafeArea(.all)
      self
    }
  }
}

struct ContentView: View {
  var body: some View {
    VStack {
      Text("Hello, World!")
    }
    .ZSC()
  }
}

Protocols — The Swift Programming Language (Swift 5.5)
Extensions — The Swift Programming Language (Swift 5.5)