【问题标题】:Multiple enum implementing protocols questions多个枚举实现协议问题
【发布时间】:2017-11-13 16:52:25
【问题描述】:

我将枚举定义为对协议 Eventable 的确认:

protocol Eventable {
    var name: String { get }
    static var all: [Eventable] { get }
}

enum MyEnum: String, Eventable {
    case bla = "bla"
    case blu = "blu"

    var name: String {
        return self.rawValue
    }

    static var all: [Eventable] {
        return [
            MyEnum.bla,
            MyEnum.blu
        ]
    }
}

我还有其他枚举,例如 MyEnum,其形式如下: 枚举 Bla:字符串,可事件 { }

我有两个问题:

  1. 对于具有字符串数据类型的枚举,我想避免重复生成变量名: var name: String 我不确定如何在 Swift 中编写它。我试图玩弄“where”子句,但没有成功。我怎样才能做到这一点?

  2. 当我编写枚举并遵守该部分的协议时: static var all: [Eventable] { get }。 我想要枚举 MyEnum,它将变量限制为: static var all: [MyEnum] { ... } 因为现在我可以在返回的数组中放入任何作为 Eventable 的元素,这不是我需要的。 除其他外,我尝试在协议中为其定义一个通用约束,但出现以下错误:

Protocol 'Eventable' 只能用作通用约束,因为 它有 Self 或关联的类型要求

非常感谢您的帮助!

【问题讨论】:

    标签: swift enums protocols


    【解决方案1】:

    第二个问题,你只需要使用Self

    protocol Eventable {
        var name: String { get }
        static var all: [Self] { get }
    }
    

    Self,类似于self,只是表示“当前类型”。

    第一个问题有点难,因为您无法真正安全地获取枚举的所有值。请参阅here 了解更多信息。我得到的最接近的是:

    extension Eventable where Self: RawRepresentable, Self.RawValue == String {
        var name: String {
            return self.rawValue
        }
    }
    

    这意味着您可以在MyEnum 中省略name 的声明,但不能省略all

    【讨论】:

    • 感谢您的回答 :) 对于第一个问题,它就像一个魅力。对于第二个问题,我在尝试使用它时遇到了我提到的错误(Protocol 'Eventable' 只能用作通用约束,因为它具有 Self 或关联的类型要求)。
    • @Toka 如果您认为我的回答回答了您的问题,请考虑通过单击该复选标记接受它!
    • 当你回答时我正在编辑我的消息,对不起。对于第二个问题,我仍然有上述问题。你知道为什么吗?
    • @Toka 你使用了我的确切代码吗?或者错误是否发生在其他地方,而不是在扩展中?基本上,错误表明您不能再将Eventable 用作方法参数或变量的类型,因为其中包含Self
    • 是的,我使用了您提供的代码。例如,我在触发错误的不同对象中有一个具有以下签名的函数:func track(event: Eventable)
    【解决方案2】:

    对于问题的一部分,我们需要扩展Eventable 协议,其中Self 继承RawRepresentable

    protocol Eventable {
        var name: String { get }
        static var all: [Self] { get }
    }
    
    extension Eventable where Self: RawRepresentable {
        var name: Self.RawValue {
            return self.rawValue
        }
    }
    
    enum MyEnum: String, Eventable {
        case bla = "bla"
        case blu = "blu"
    
        static var all: [MyEnum] = [bla, blu]
    }
    

    对于您问题的第二部分,我们需要配置函数来处理泛型类型

    我建议也将函数设为通用,这里是一个示例

    func printEnum<T: Eventable>(_ event: T) {
        print(event.name)
    }
    

    我们可以将它用于任何确认到 Eventable 的对象

    printEnum(MyEnum.bla)
    

    【讨论】:

    • 谢谢你的回答,我会试一试:)
    猜你喜欢
    • 2016-05-09
    • 2016-04-26
    • 1970-01-01
    • 1970-01-01
    • 2018-05-22
    • 2018-07-28
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    相关资源
    最近更新 更多