返回通用枚举

时间:2017-08-09 15:31:33

标签: swift generics enums

我试图达到这个效果:

enum Foo: Int { case a, b, c, d }
enum Bar: Int { case a, b, c, d }

func generate<T: RawRepresentable>(using index: Int) -> T
{
    guard let output = T(rawValue: index) else { preconditionFailure() }
    return output
}

但我收到错误:

Playground execution failed: error: GenericEnums.playground:18:24: error: cannot invoke initializer for type 'T' with an argument list of type '(rawValue: Int)'
    guard let output = T(rawValue: index) else { preconditionFailure() }
                       ^

GenericEnums.playground:18:24: note: expected an argument list of type '(rawValue: Self.RawValue)'
    guard let output = T(rawValue: index) else { preconditionFailure() }

我哪里错了?

3 个答案:

答案 0 :(得分:3)

首先,index不应该是Int,而应该是T.RawValue,因为RawRepresentable协议没有指定RawValue }&#39; s类型为Int。其次,如果您不想键入为generate指定返回值的变量的注释,则应将泛型类型参数T应用于表示您的类型的输入参数想要生成。

以下是您的通用功能的工作和测试实现。 value参数必须是您要生成的enum的类型。

enum Foo: Int { case a, b, c, d }
enum Bar: Int { case a, b, c, d }

func generate<T: RawRepresentable>(value ofClass: T.Type,using index: T.RawValue) -> T {
    guard let output = T(rawValue: index) else { preconditionFailure() }
    return output
}

//the output of this version needs to be assigned to a type annotated variable, 
//otherwise the compiler cannot figure out the exact type that T represents
func generate<T: RawRepresentable>(using index: T.RawValue) -> T {
    guard let output = T(rawValue: index) else { preconditionFailure() }
    return output
}

generate(value:Foo.self, using: 1) //returns Foo.b
let a: Bar = generate(using: 0)    //returns Bar.a

答案 1 :(得分:2)

DávidPásztor的答案是更通用的答案,应该在大多数情况下使用。

但是,如果您只想使用基于Int的{​​{1}}类型执行某些操作, 你可以这样做:

RawRepresentable

答案 2 :(得分:0)

我个人认为你过分思考这个问题。如果在提供错误的原始值时目标是崩溃,请执行以下操作:

extension RawRepresentable {
    init(rawValueOrDie what:RawValue) {
        self.init(rawValue:what)!
    }
}