スウィフト3
(私はあなたの例ではCollection
でIndexableBase
を交換しましたが、あなたは後者を好む必要があります)
この回避策を使用することができます
Swift 3によると、プロトコル構成は、前protocol<...>
コンストラクト上rator &
、受け入れられ、進化提案実装に記載されているように:あなたはパラメータでT
プレースホルダで結合型制約を配置することができるプロトコルの組成物を使用し、したがって
をリスト:
class MyCustomClass<T: Equatable & Collection> { /* ... */ }
プロトコル構成の代わりに、where
句を使用して、いくつかのタイプ(およびサブタイプ)制約を結合することもできます。受け入れられ、実装進化の提案に従って:
class MyCustomClass<T: Equatable> where T: Comparable { /* ... */ }
か:
where
句は、その場合にはあなたの例では、読んでいました、宣言の最後に移動されました、宣言の最後にwhere
句を付けて完全なプロトコル構成を配置することもできます。
class MyCustomClass<T> where T: Equatable & Comparable { /* ... */ }
、私たちはどのようなスタイルを好むでしょうか?
興味深い議論は、この特定のテーマがSwift APIガイドラインではないため、「ベストプラクティス」と考えるべきものです。我々は
- パラメータリスト内のすべての(主要タイプ)制約、または宣言の終わりに
- すべての制約、または
- がに置かれたパラメータリストなどの一部の持つ制約を分割を置いてください宣言の終わり?
は、我々が構築我々は、それ自体で、我々は型制約を配置することができるためにどのassociatedtype
を保持型制約(Doable
)として使用する予定のプロトコルを持っている次の不自然な例を考えます。
私は
the evolution thread that that brought forth SE-0081からアップルdevのジョーGroffのを引用します、以下のすべての3つの選択肢が有効である、上記の構文的
// alternative #1
func foo<T: Equatable & Doable>(_ bar: T) ->() where T.U: Comparable { /* ... */ }
// alternative #2
func foo<T: Equatable>(_ bar: T) ->() where T: Doable, T.U: Comparable { /* ... */ }
// alternative #3
func foo<T>(_ bar: T) ->() where T: Equatable & Doable, T.U: Comparable { /* ... */ }
を異なる方法を使用して
protocol Doable {
associatedtype U
}
:それは審判の判定です
。それは多くの場合、一般的な パラメータがアップフロント呼び出す価値がある少なくとも一つの重要なプロトコルまたはベース クラスによって制約されるというのが私の気持ちですので、Collection
を追放せずに
func foo<C: Collection>(x: C) -> C.Element
のような 事を許可するのが妥当です拘束は宣言の正面からあまりにも遠くにある です。
したがって、上記の不自然な例では、一般的なプレースホルダT
に直接適用型制約のためのプロトコル構成を使用することが適切であるかもしれない、とT.U
のサブタイプの制約があるのに対し、パラメータリストにこれらの制約を課します宣言の最後に置かれる。すなわち、上記の代替#1。
whereオペレータが私にとって完璧に動作するので(Xcode 8.1、Swift 3)、このソリューションを使用しています。 – altralaser
@altralaser Swift 3でこれが「うまくいく」場合であっても、それは警告、つまり[** emphasis ** mine]を与えるはずです:_ "警告:' 'where' ' Swift **の将来のバージョンでは削除されます。したがって、Swift 3の最新のソリューションを使用したいと思うかもしれません。あるいは、Swiftの将来のアップデートで実装が壊れるかもしれません(Swift 3-up-dateバージョンの他の2つの回答を参照してください)。 – dfri