2016-11-17 84 views
1

我遇到了一個概念性問題,正在尋找建議。我有一個基類定義所有的共同性質的給定對象類型的:使用高級限制Swift協議

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

許多這些窗口小部件的共享其它特性和功能,容易進行分組。性能/功能很好地融入協議:

protocol WidgetryA { 
    func widgetAFunc() 
} 

protocol WidgetryB { 
    func widgetBFunc() 
} 

可以很容易地擴展Widget類遵守這些各種協​​議:

​​

注意,窗口小部件可以遵循多個協議。到目前爲止沒有問題!我想要做的以及我正在努力的是以下內容......具有某個Widget.type值的小部件基本上不應該符合給定的Widgetry協議。因此,例如:

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

現在我能做些什麼總值和不雅狀護套()荷蘭國際集團在協議功能,以防止錯誤Widget.type的小工具,從撥打電話,他們不應該。我覺得關聯類型可能會提供一個可行的途徑來實現我想要的,但我正在努力想出一個可行的構造。任何想法或建議,將不勝感激!

+0

Widget的''''屬性是一個存儲的屬性(而不是關聯的類型)。如果你的例子是合法的(以某種形式),這將意味着某些給定的_type_(這是本質定義的類型)可用的方法將在_runtime_期間被決定(基於類型的某個屬性的_value_),在Swifts強大的打字系統中是不可能的。通常的用法是限制類型的擴展(類型''associatedtype')滿足某些條件,但所有這些邏輯在編譯期間都會被解析。 – dfri

+0

您無法約束基於運行時屬性的協議。如果您需要進行字符串分類,我強烈建議使用枚舉。 – PeejWeej

回答

0

爲一對夫婦的原因,雨燕描述這是不可能的:

  1. 雨燕編譯器不知道的「類型」屬性運行時的值將是什麼

  2. 斯威夫特泛型和協議擴展不支持基於約束的排除/禁止/刪除方法和實現,通用約束也不支持不是某種類型的匹配類型。

但是,而不是使用字符串類型,我會建議作出了Widget的「類型」的協議本身,然後通過協議擴展到各種小工具,符合正確類型的協議只實例添加的實現(S)

+0

上面1和2的解釋非常清楚。謝謝。你能否詳細解釋一下你的答案的最後部分?如果我爲Widget使用WidgetType協議,我還不清楚如何構建Widgetry協議,擴展WidgetType協議或爲Widget類提供默認協議實現以限制給定協議的使用。這裏有一些難題,我仍然無法看到不幸的是! –

1

您可以執行協議的擴展:

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

所以這widgetAFunc將只針對那些Foo型的,並符合WidgetryA協議類實現。當然,你必須創建Widget的子類。