2016-11-17 85 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的子类。