💬

Swiftのジェネリクス

2024/08/30に公開

ジェネリクス とは?

ジェネリクスは、Swiftの強力な機能の一つであり、型に依存しない汎用的な関数や型を作成することを可能にします。これにより、コードの再利用性が向上し、型安全性も確保されます。たとえば、異なる型のデータを一つの関数で処理できるようになるため、コードがシンプルで保守しやすくなります。
Swiftのジェネリクスについての詳細

実際の使用例を見た方がイメージしやすいため具体例を見ていきます。

実際の使い道

例えば、以下の画像のように異なる型のデータを表示するためのUIを作成する場面を考えてみましょう。このような場合、通常はそれぞれの型に対して別々の関数を用意する必要があります。しかし、ジェネリクスを使えば、異なる型を一つの関数で処理できるため、コードが簡潔になります。

実装手順

私の場合、異なる型のデータをすべて文字列にキャストして処理する実装を思いつきました。


struct ZennTestView: View {

    var body: some View {
        createHStackView(title: "文字列", value: "Hello world")
        createHStackView(title: "整数", value: String(123))
        createHStackView(title: "小数", value: String(123.456))
        createHStackView(title: "真偽値", value: String(true))
        createHStackView(title: "日付", value: Date().description)
    }
}
func createHStackView(title: String, value: String) -> some View {
    Group {
        HStack {
            Text(title)
                .frame(width: 100, alignment: .leading)
            Text(value)
                .frame(width: 100, alignment: .leading)
        }
        Divider()
    }
    
}

これでも要件は満たせますが、createHStackViewメソッドを実行する際の引数をいちいち文字列にキャストして実行する必要があるため手間がかかり、コードが冗長になりがちです。
そこで、ジェネリクスを使って、異なる型のデータを効率的に処理する方法を紹介します。

CustomStringConvertibleプロトコルの活用

先に実装を紹介します。

struct ZennTestView: View {
    var body: some View {
        createHStackView(title: "文字列", value: "Hello world")
        createHStackView(title: "整数", value: 123)
        createHStackView(title: "小数", value: 123.456)
        createHStackView(title: "真偽値", value: true)
        createHStackView(title: "日付", value: Date())
    }
}

func createHStackView<T: CustomStringConvertible>(title: String, value: T) -> some View {
    Group {
        HStack {
            Text(title)
                .frame(width: 100, alignment: .leading)
            Text(value.description)
                .frame(width: 100, alignment: .leading)
        }
        Divider()
    }
    
}

String,Int,Date,Double,Boolクラスは全てCustomStringConvertibleプロトコルに準拠しているため、CustomStringConvertibleをジェネリクスとして指定します。Apple公式ドキュメント(String)

また、CustomStringConvertibleプロトコルに準拠しているものは全てdescriptionプロパティを保持しているため上記の実装で実現可能になります。

結論

ジェネリクスをマスターすることで、より柔軟で効率的なSwiftコードを作成できるようになります。今回の例では、ジェネリクスを使って異なる型のデータを処理する方法を学びましたが、これをさらに応用して複雑なデータ構造やアルゴリズムにも挑戦してみましょう。

お願い

実務経験も少なく、Swiftは学習中の段階であるため、記事の内容にご指摘やアドバイス等ありましたらコメントいただけると幸いです。

Discussion