2016-12-07 11 views
6

内の1つのプロトコルよりも、私は、ジェネリック型指定されたクラスと型の制約を使用します。しかし、私が第2のプロトコルを使用したい場合はどうなりますか?その他の型制約

class MyCustomClass<T : Equatable, IndexableBase> { 
    var a: Array<T> 
    init() { 
    a = Array<T>() 
    } 
} 

1つの引数の代わりに2を使用する必要があるため、イニシャライザが失敗するということです。私は理解していない。

答えて

1

あなたは

class MyCustomClass<T: Equatable where T: IndexableBase > { 
    var a: Array<T> 
    init() { 
     a = Array<T>() 
    } 
} 
+0

whereオペレータが私にとって完璧に動作するので(Xcode 8.1、Swift 3)、このソリューションを使用しています。 – altralaser

+2

@altralaser Swift 3でこれが「うまくいく」場合であっても、それは警告、つまり[** emphasis ** mine]を与えるはずです:_ "警告:' 'where' ' Swift **の将来のバージョンでは削除されます。したがって、Swift 3の最新のソリューションを使用したいと思うかもしれません。あるいは、Swiftの将来のアップデートで実装が壊れるかもしれません(Swift 3-up-dateバージョンの他の2つの回答を参照してください)。 – dfri

14

スウィフト3

(私はあなたの例ではCollectionIndexableBaseを交換しましたが、あなたは後者を好む必要があります)


この回避策を使用することができます

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。

+0

これは印象的です!しかし、[この提案](https://github.com/apple/swift-evolution/blob/master/proposals/0081-move-where-expression.md)についてどう思いますか?私はそれに基づいて答えた... btw私はdownvoterではない、私はupvoter :) –

+0

@AhmadFありがとう。その提案は私の答えにも含まれており、私はそれが新しいプロトコル構成(同じコンセプトの2つの部分)と同様に適切であると信じています。興味深い議論は、スウィフトAPIガイドラインには明記されていないため、ベストプラクティスと考えるべきものです。すべての制約を宣言の最後に置くのか、それともサブタイプの制約だけを置くのでしょうか?進化の提案SE-0081に関連した興味深い議論があります。そこにはいくつかの考えと、異なる制約を置く場所の長所と短所が含まれています。私は私の答えにこの議論の少しを含めるでしょう。 – dfri

+0

正直言って私はが "クーラー"であることを知っていました。 –

関連する問題