2016-11-17 9 views
1

私は概念的な問題に遭遇し、アドバイスを探しています。これらのウィジェットのアドバンス付きSwiftプロトコルの制限

class Widget { 
    var id: Int 
    var type: String 
} 

多くが容易にグループ化され、他の特性と機能を共有する:私は、共通のプロパティ指定されたオブジェクトタイプのすべてを定義する基本クラスを有します。性質/機能は、プロトコルにうまくフィット:

protocol WidgetryA { 
    func widgetAFunc() 
} 

protocol WidgetryB { 
    func widgetBFunc() 
} 

それは、これらのさまざまなプロトコルに準拠するようにウィジェットクラスを拡張するのは簡単です:ウィジェットは、複数のプロトコルに準拠することができることを

​​

注意。これまでのところ問題ありません!私がやりたいこと、私が苦労していることは次の通りです...特定のWidget.type値を持つウィジェットは、指定されたウィジェットプロトコルに準拠することが基本的に禁止されています。だから、例えば:

// this obviously doesn't work with where -- is there an alternative? 
extension Widget: WidgetryA where Self.type == "foo" { 
    func widgetAFunc() { } 
} 

今、私は、彼らがいけないの呼び出しを行うことから、間違ったWidget.typeのウィジェットを防ぐために、プロトコル機能でガード()INGのようなグロスと無粋な何かを行うことができます。私は関連タイプが私が望むものを達成するための実行可能な道を提供するかもしれないと感じていますが、私は働くコンストラクトを思いついています。どんな考えや助言もありがとう!

+0

「ウィジェット」の 'type'プロパティは、ストアされたプロパティです(関連タイプなどではありません)。あなたの例が合法であるなら(何らかの形で)、これは_type_(エッセンスが型を定義する)に利用可能なメソッドが_runtime_(型のいくつかのプロパティの_value_に基づいて)中に決定されることを意味します。スウィフトの強タイピングシステムでは不可能です。一般的な使い方は、いくつかの型の型( 'associatedtype')が何らかの条件を満たす場合に型に拡張を制限することですが、そのようなすべての論理はコンパイル時に解決されます。 – dfri

+0

ランタイムアトリビュートに基づいてプロトコルを制約することはできません。文字列型の違いを行う必要がある場合は、enumを使用することを強くお勧めします。 – PeejWeej

答えて

0

カップルの理由のためにスウィフトで説明したようにこれは不可能です。

  1. スウィフトコンパイラは、「タイプ」プロパティのランタイム値が

  2. スウィフトさんがどうなるか分かりません。ジェネリックスやプロトコル拡張は、制約に基づいてメソッドや実装を除外/除外/削除することをサポートしていません。

しかし、かなりの種類の文字列を使用するよりも、私はウィジェット「タイプ」プロトコル自体を作ることをお勧めし、正しい型のプロトコルに準拠するウィジェットであるインスタンスのみへのプロトコル拡張を経て実装を追加しますあなたは、プロトコルの拡張を行うことができます

+0

上記1と2の説明は非常に明確です。ありがとう。あなたは答えの最後の部分で少し詳しく説明できますか?私がWidgetにWidgetTypeプロトコルを使用すると、Widgetryプロトコルをどのように構造化し、WidgetTypeプロトコルを拡張したり、Widgetクラスのデフォルトのプロトコル実装を提供して、特定のプロトコルの使用を制限するかについてはまだ分かりません。私はまだ残念ながら見ることができませんここにパズルの一部があります! –

1

(S):ので、このwidgetAFuncのみFooタイプのものであり、WidgetryAプロトコルに準拠したクラスのために実装されます

extension WidgetryA where Self: Foo { 
    func widgetAFunc() { } 
} 

。もちろん、Widgetのサブクラスを作成する必要があります。

関連する問題