swift - 如何编写协议(protocol)扩展以从 Swift 枚举中获取所有 rawValues

标签 swift generics enums protocols generator

我想做的是创建一个协议(protocol)扩展来从枚举中获取一组原始值。例如说我有以下内容:

enum TestType: String, EnumIteratable {
    case unitTest = "Unit Test"
    case uiTest = "UI Test"
}

class EnumIterator: NSObject {
    class func iterateEnum<T: Hashable>(_: T.Type) -> AnyGenerator<T>  {
        var i = 0
        return anyGenerator {
            let next = withUnsafePointer(&i) { UnsafePointer<T>($0).memory }
            return next.hashValue == i++ ? next : nil
        }
    }

   class func getValues<T: Hashable>(_: T.Type) -> [T] {
        let iterator = self.iterateEnum(T)
        var returnArray = [T]()
        for val in iterator {
            returnArray.append(val)
        }
        return returnArray
    }

}

如何实现 EnumIteratable 协议(protocol),以便调用 TestType.getRawValues() 并让它返回所有原始枚举值的字符串数组?

谢谢!

最佳答案

Scott 的解决方案可能就是您想要的。但是,如果您正在寻找可以应用于任意 future 枚举并允许其他情况的更通用的东西,您可以试试这个:

首先,您需要一种方法来迭代枚举案例。我从这里使用了这个实现:https://stackoverflow.com/a/28341290/914887

func iterateEnum<T: Hashable>(_: T.Type) -> AnyGenerator<T> {
    var i = 0
    return anyGenerator {
        let next = withUnsafePointer(&i) { UnsafePointer<T>($0).memory }
        return next.hashValue == i++ ? next : nil
    }
}

然后,您可以创建您的协议(protocol),它定义了您想要的静态函数:

protocol EnumIteratable {
    typealias ENUM_TYPE:Hashable, RawRepresentable = Self
    static func getAllValues() -> [ ENUM_TYPE ]
    static func getRawValues() -> [ ENUM_TYPE.RawValue ]
}

我使用关联类型来允许符合规范的枚举将它们的类型指定给协议(protocol)。 getAllValues 不是绝对必要的,但它简化了逻辑。

然后,您可以定义您的通用默认实现:

extension EnumIteratable {
    static func getAllValues() -> [ ENUM_TYPE ]
    {
        var retval = [ ENUM_TYPE ]()
        for item in iterateEnum( ENUM_TYPE )
        {
            retval.append( item )
        }
        return retval
    }

    static func getRawValues() -> [ ENUM_TYPE.RawValue ]
    {
        return getAllValues().map( { ( item:ENUM_TYPE ) -> ENUM_TYPE.RawValue in item.rawValue } )
    }
}

最后,您需要做的就是在需要迭代枚举时随时遵守该协议(protocol):

enum TestType: String, EnumIteratable {
    case unitTest = "Unit Test"
    case uiTest = "UI Test"
}

TestType.getRawValues()

这里的优点是,我可以为 integrationTest 添加一个新案例,我只需要在一个地方添加它。

关于swift - 如何编写协议(protocol)扩展以从 Swift 枚举中获取所有 rawValues,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33589055/

相关文章:

java - 谷歌 Guice + 泛型 : Is there some magic behind the curtains?

ios - Swift:尝试与 Web API 通信时出错

c# - 如何在 Xamarin 中使用 UITextView 为 iOS 实现隐藏/显示密码样式体验?

swift - “ fatal error :在展开可选值时意外发现nil”是什么意思?

java - 具有类型安全类参数的通用(非静态)方法,它是如何工作的?

arrays - 数组扩展,其中 Element 是 Optional 并且返回类型是 Wrapped

c++ - 我应该如何循环 C++11 中的枚举类?

java - 接口(interface)中有更多枚举

java - Eclipse 编译器和 javac 之间的差异 - 枚举、接口(interface)和泛型

swift - 将现有的 iOS 应用程序从 objective-c 迁移到 Swift