swift - 具有关联类型类型转换的保护案例的单个表达式?

标签 swift swift3

我有以下枚举:

enum JSONData {
    case dict([String:Any])
    case array([Any])
}

我想使用 guard case let 进行模式匹配赋值类型转换。我不仅要确保 someData.array,而且它的关联类型是 [Int] 而不仅仅是 [任何]。这可能用一个表达式吗?类似于以下内容:

let someData: JSONData = someJSONData()
guard case let .array(anArray as [Int]) = someData
else { return }

但是上面没有编译;错误是 无法使用类型为“[Int]”的向下转型模式值。我知道这可以通过以下方式实现,但如果可能的话,我宁愿用一个表达式来实现。

guard case let .array(_anArray) = someData, let anArray = _anArray as? [Int]
else { return }

2018 年 4 月 27 日编辑:此情况的更新:您现在可以使用以下语法,只要转换类型不是 Collection:

enum JSONData {
    case dict([String:Any])
    case array(Any)  // Any, not [Any]
}

func f() {
    let intArray: JSONData = .array(1)
    guard case .array(let a as Int) = intArray else {
        return
    }
    print("a is \(a)")
}

f()  // "a is 1"

如果您尝试使用诸如 [Int] 之类的集合类型,您会收到错误消息 error: collection downcast in cast pattern is not implemented;改用对“[Int]”的显式向下转换

最佳答案

由于 Swift 模式匹配实现的限制,您尝试执行的操作是不可能的。居然叫了here :

// FIXME: We don't currently allow subpatterns for "isa" patterns that
// require interesting conditional downcasts.

This answer试图解释原因,但不尽如人意。但是,它们确实指出了一条有趣的信息,如果您不使用泛型作为关联值,这些信息可以使事情正常进行。

以下代码实现了单行代码,但失去了一些其他功能:

enum JSONData {
    case dict(Any)
    case array(Any)
}

let someData: JSONData = JSONData.array([1])

func test() {
    guard case .array(let anArray as [Int]) = someData else {
        return
    }

    print(anArray)
}

或者,可以通过枚举定义中的实用函数将基础值转换为 Any 来实现相同的衬里。此路由保留了案例与其关联值类型之间的良好关系。

enum JSONData {
    case dict([String : Any])
    case array(Array<Any>)

    func value() -> Any {
        switch self {
        case .dict(let x):
            return x
        case .array(let x):
            return x
        }
    }
}

// This coercion only works if the case is .array with a type of Int
guard let array = someData.value() as? [Int] else {
    return false
}

关于swift - 具有关联类型类型转换的保护案例的单个表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45124104/

相关文章:

swift - 从 swift 1.0 到 1.2 的固定功能

ios - 重用 UITableViewCell 时无法重置 UILabel attributeText

ios - 如何修复 Xcode 版本 11.0 测试版 Canvas 崩溃?

ios - 不能在属性初始值设定项中使用实例成员

ios - 示例代码更改为防护并指出崩溃

swift - 无法更改 tabBar 内的选项卡(tabBar : didSelectItem item:)

ios - 我的应用程序中的 iAd 不起作用

swift - 计时器不会从开始/暂停切换按钮开始

ios - popToViewController 后 pushViewController 上的应用程序崩溃

swift - 将选择器添加到 UIStepper 的 addTarget 函数时出错 - Swift 3