限制Swift协议与高级在哪里

时间:2016-11-17 16:52:18

标签: ios swift swift-protocols

我遇到了一个概念问题,正在寻求建议。我有一个基类,它定义给定对象类型的所有常见属性:

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

其中许多小部件共享其他易于分组的属性和功能。属性/功能非常适合协议:

protocol WidgetryA {
    func widgetAFunc()
}

protocol WidgetryB {
    func widgetBFunc()
}

很容易扩展Widget类以符合这些不同的协议:

extension Widget: WidgetryA {
    func widgetAFunc() { }
}

请注意,窗口小部件可能符合多种协议。到目前为止没问题!我想做的,以及我正在努力解决的问题是:具有某个Widget.type值的小部件应该基本上不允许符合给定的Widgetry协议。例如:

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

现在,我可以在协议功能中执行像guard()一样严格且不优雅的事情,以防止错误的Widget.type的Widgets进行他们不应该进行的调用。我觉得相关的类型可能提供了一条可行的途径来实现我想要的东西,但我正在努力想出一个有效的结构。任何想法或建议将不胜感激!

3 个答案:

答案 0 :(得分:1)

您可以对协议进行扩展:

mtcars %>%
  nest(-cyl) %>% 
  mutate(fit = map(data, ~lm(mpg ~ wt, data = .)),
         summary = map(fit, glance),
         r_sq = map_dbl(summary, "r.squared"))

因此,此extension WidgetryA where Self: Foo { func widgetAFunc() { } } 仅适用于widgetAFunc类型且符合Foo协议的类。当然,您必须创建WidgetryA的子类。

答案 1 :(得分:0)

这不可能像Swift中描述的那样有几个原因:

  1. Swift编译器不知道“type”属性的运行时值是什么

  2. Swift的泛型和协议扩展不支持基于约束排除/禁止/删除方法和实现,通用约束也不支持不匹配的匹配类型。

  3. 但是,我建议不要使用类型字符串,而是建议将Widget“类型”作为协议本身,然后通过协议扩展将实现添加到仅符合正确类型协议的小部件的实例< / p>

答案 2 :(得分:0)

限制特定类采用的协议,如下所示:

My Protocol: MyViewController { 
  func myMethod()
}