可以在 Swift 中将枚举类型名称作为参数传递吗?

Posted

技术标签:

【中文标题】可以在 Swift 中将枚举类型名称作为参数传递吗?【英文标题】:Possible to pass an enum type name as an argument in 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的签名是什么?

【问题讨论】:

【参考方案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()

以上是关于可以在 Swift 中将枚举类型名称作为参数传递吗?的主要内容,如果未能解决你的问题,请参考以下文章

Swift:将类型作为参数传递

如何在 VB NET 中将方法名称作为过程的参数传递

C#中的枚举类型如何传递参数呢?

在 Swift 中将函数作为参数传递

如何在 Swift 4 中将 Encodable 或 Decodable 作为参数传递?

我们可以在 PHP 中的任何函数中将数组作为参数传递吗?