6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Swift】TargetedExtensionとは

Last updated at Posted at 2021-03-29

はじめに

僕のSwiftで最も好きな文法はExtensionです笑
基礎的なExtensionの使い方はこちらをみてみてください。
TargetedExtensionというものがあるらしいので、みていきましょう。

Extensionとは?

詳細なエクステンションの説明は省きますが、エクステンションは以下のように構造体やクラス、プロトコルを拡張してメソッドなどを追加できます。
例を見てみましょう。

extension Int {
    var minus10: Self {
        return self - 10
    }
    func plus100() -> Self {
        return self + 100
    }
}
print(200.minus10) //190
print(200.plus100().plus100().minus10) //390

こちらも合わせてご覧ください(メソッドチェーン)

TargetedExtensionとは?

前項の例だといいのですが、命名によってはこのメソッドは既にあるものなのか、自分で作ったものなのかわからない場合がありますし、Xcodeの予測変換でメソッドやプロパティが自分で作った数だけ多くなるので、見辛くなってしまうかもしれません。できればXcodeの補完を汚さずに、自作のメソッドなどにアクセスしたいです。
このような時に役に立つのがTargetedExtensionです。
前項のプログラムを修正していきましょう。

protocol SomeComapatible {
    associatedtype ComapatibleType
    var own: ComapatibleType { get }
}

class Some<T> {
    private let base: T
    init(_ base: T) {
        self.base = base
    }
}

extension SomeComapatible {
    var own: Some<Self> {
        return Some(self)
    }
}

extension Int: SomeComapatible { }

extension Some where T == Int {
    var minus10: Int {
        return base - 10
    }
    func plus100() -> Int {
        return base + 100
    }
}

こうすることで、以下のようにownを間に挟まないとminus10プロパティやplus100メソッドにアクセスできないようにできました。

print(1000.minus10) //エラー
print(1000.own.plus100()) //1100

解説

ステップ1

このプロトコルを採用したものはownプロパティを持つようにする。

protocol SomeComapatible {
    associatedtype ComapatibleType
    var own: ComapatibleType { get }
}

ステップ2

Intに先ほどのプロパティを準拠させます。しかし、ownプロパティの実装がありませんので、次で実装しましょう。

extension Int: SomeComapatible { }

ステップ3

以下のように実装します。Some<Self>SelfはプロトコルSomeComapatibleを準拠させた具体的な型なので、今回はIntですね。
そして、return Some(self)selfprint(1000.own.plus100())このように書いた時の1000のことです。
このように、ジェネリクスも用いてあげることで、IntだけでなくStringなどでも同じownを利用する事ができます。

class Some<T> {
    private let base: T
    init(_ base: T) {
        self.base = base
    }
}

extension SomeComapatible {
    var own: Some<Self> {
        return Some(self)
    }
}

ステップ4

では、具体的にメソッドなどを定義していきます。

extension Some where T == Int {
    var minus10: Int {
        return base - 10
    }
    func plus100() -> Int {
        return base + 100
    }
}

このminus10plus100TIntの時のみ使えると言う条件を付け足しました。
baseIntなので、実際は1000などが入ってきます。

おわりに

メソッドチェーンはこのような考慮がかけています。ぜひ、この記事を参考に書き換えてみてください。

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?