1. ホーム
  2. swift

[解決済み] Swiftの多重型制約

2022-05-13 07:39:20

質問

例えば、以下のようなプロトコルがあるとします。

protocol SomeProtocol {

}

protocol SomeOtherProtocol {

}

さて、一般的な型を受け取る関数が欲しいが、その型は以下のものに従わなければならない場合。 SomeProtocol とすることができました。

func someFunc<T: SomeProtocol>(arg: T) {
    // do stuff
}

しかし、複数のプロトコルに対応した型制約を追加する方法はないのでしょうか?

func bothFunc<T: SomeProtocol | SomeOtherProtocol>(arg: T) {

}

似たようなものはカンマを使いますが、この場合、違う型の宣言を始めることになります。 以下は、私が試したものです。

<T: SomeProtocol | SomeOtherProtocol>
<T: SomeProtocol , SomeOtherProtocol>
<T: SomeProtocol : SomeOtherProtocol>

どのように解決するのですか?

あなたは を使うことで、カンマで区切っていくつでも要件を指定することができます(すべて満たさなければなりません)。

Swift 2:

func someFunc<T where T:SomeProtocol, T:SomeOtherProtocol>(arg: T) {
    // stuff
}

Swift 3 & 4:

func someFunc<T: SomeProtocol & SomeOtherProtocol>(arg: T) {
    // stuff
}

または、より強力なwhere節を使用します。

func someFunc<T>(arg: T) where T:SomeProtocol, T:SomeOtherProtocol{
    // stuff
}

もちろん、プロトコル合成(例. protocol<SomeProtocol, SomeOtherProtocol> ) を使うこともできますが、少し柔軟性に欠けます。

を使って where を使うことで、複数の型が関係するケースに対応できます。

複数の場所で再利用するためにプロトコルを構成したい場合や、構成したプロトコルに意味のある名前を付けたい場合もあります。

Swift 5:

func someFunc(arg: SomeProtocol & SomeOtherProtocol) { 
    // stuff
}

これはプロトコルが引数の隣にあるため、より自然に感じられます。