【问题标题】:Possible to pass an enum type name as an argument in Swift?可以在 Swift 中将枚举类型名称作为参数传递吗?
【发布时间】:2016-12-12 02:57:21
【问题描述】:

我试图弄清楚是否可以像在 Swift 中传递 Class 对象一样传递枚举类型。

我的实际用例比这要复杂一些,但为了讨论,假设我有两个 Int 枚举:

enum Foo: Int, CustomStringConvertible {
    case firstFoo = 0
    case anotherFoo = 1
    var description: String {
        switch self {
        case .firstFoo:
            return "Hello Foo"
        case .anotherFoo:
            return "Goodbye Foo"
        }
    }
}

enum Bar: Int, CustomStringConvertible {
    case firstBar = 0
    case anotherBar = 1
    var description: String {
        switch self {
        case . firstBar:
            return "Hello Bar"
        case . anotherBar:
            return "Goodbye Bar"
        }
    }
}

我希望能够编写这样的函数:

func justAnExample(whichEnum: enum) {
    let val = whichEnum(rawValue: 0)
    print("description: \(String(val))")
}

然后像这样使用它:

justAnExample(Foo)
// prints: "description: Hello Foo"
justAnExample(Bar)
// prints: "description: Hello Bar"

这可能吗?如果有,函数声明中whichEnum的签名是什么?

【问题讨论】:

    标签: swift types enums


    【解决方案1】:

    您可以利用具有原始值的枚举自动符合RawRepresentable 协议这一事实。您可以定义一个通用函数,该函数采用给定类型T(拼写为T.Type)的元类型参数,其中TRawRepresentable,同样在您的情况下,它的RawValueInt .

    这将允许您传入FooBar 的元类型,分别拼写为Foo.selfBar.self

    func justAnExample<T : RawRepresentable>(_ enumType: T.Type) where T.RawValue == Int {
    
      // Note that an explicit use of init is required when creating an instance from a
      // metatype. We're also using a guard, as `init?(rawValue:)` is failable.
      guard let val = enumType.init(rawValue: 0) else { return }
      print("description: \(val)")
    }
    
    justAnExample(Foo.self) // prints: "description: Hello Foo"
    justAnExample(Bar.self) // prints: "description: Hello Bar"
    

    【讨论】:

    • 如何在 swift 4 中编写这个,该方法还返回一个值?使用“where T.RawValue == Int -> String”,它认为 RawValue 是 (Int)->String 编辑:方法返回类型出现在 where 子句之前!
    【解决方案2】:

    一种解决方案是为 RawRepresentable E.G. 编写扩展

    extension RawRepresentable where RawValue == Int{
    
        static func testPrint() {
            print(Self(rawValue: 0))
        }
    }
    enum Thing: Int {
        case Test = 0
    }
    // prints "Optional(Thing.Test)"
    Thing.testPrint()
    

    那么你就不用担心传递任何东西了。当然,它不仅仅适用于枚举

    【讨论】:

    • 这没有用,因为我没有Thing。我正在尝试将ThingAThingB 作为参数传递,
    • 如果是 ThingA: Int 和 ThingB: Int 应该没问题。您还可以为任何其他 RawValue 类型编写扩展
    • 这并不能解决问题。我想打电话给someOtherMethod(Thing),而不是Thing.testPrint()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-09
    • 2020-06-22
    • 1970-01-01
    • 2018-10-11
    • 2012-04-18
    相关资源
    最近更新 更多