从函数返回通用的CaseIterable符合类型

时间:2019-01-28 10:58:19

标签: swift generics enums swift-protocols

我正在尝试实现一个协议,该协议需要一个函数,该函数应返回符合Type类型的CaseIterable。当我调用该函数时,我希望能够在返回的泛型类型上调用.allCases。不幸的是,编译器不允许我这样做。

protocol FooDataSource: class {
    func caseIterable<T: CaseIterable>(for foo: Foo) -> T.Type
}

class Foo {
    weak var dataSource: FooDataSource?

    func callAllCasesProperty() {
        let a = self.dataSource?.caseIterable(for: self).allCases
    }
}

尝试在操场上运行该代码时,我得到:

  

错误:experiments.playground:7:58:错误:无法推断出通用参数T let a = self.dataSource?.caseIterable(for: self).allCases

有没有办法实现预期的功能?

1 个答案:

答案 0 :(得分:0)

虽然我不确定您要完成的工作,但看起来您可以使用对类型有一些特定约束的泛型函数。通过将T限制为RawRepresentable和CaseIterable,您可以将枚举类型作为参数传递,并在函数中调用allCases。

enum Direction: String, CaseIterable {
    case north
    case south
    case east
    case west
}

enum Weight: Int, CaseIterable {
    case Light = 1
    case Mid = 4
    case Heavy = 10
}

func genericMethod<T : RawRepresentable & CaseIterable>(enum enumType: T.Type) {
    for aCase in enumType.allCases {
        print(aCase.rawValue)
    }
}

genericMethod(enum: Direction.self) // prints -> north, south, east, west
genericMethod(enum: Weight.self) // prints -> 1, 4, 10

您还可以像这样进一步约束类型T:

func genericMethodWithRawConstraint<T : RawRepresentable & CaseIterable>(enum enumType: T.Type) where T.RawValue == String {
    for aCase in enumType.allCases {
        print(aCase.rawValue)
    }
}

//Will not compile because Weight is of type Int
//genericMethodWithRawConstraint(enum: Weight.self)