快速模式匹配-在单个语句中进行切换,向下转换和可选绑定

时间:2018-07-08 20:47:12

标签: swift pattern-matching optional-binding

是否可以合并下面的switch语句以包含可选绑定?

一些背景知识...

首先这是我的结果类型:

enum Result<Value> {
    case success(Value)
    case failure(Swift.Error)
}

Facebook SDK的扩展程序:

func start(_ completionHandler: @escaping (Result<Any>) -> Void) -> FBSDKGraphRequestConnection
{
    return start() { (_, response, error) in
        switch (response, error) {
        case (.some(let result), .none):
            completionHandler(Result(value: result))

        case (.none, .some(let error)):
            completionHandler(Result(error: error))

        case (.none, .none), (.some, .some):
            preconditionFailure("Unexpected State")
        }
    }
}

最后,我要重构的一点代码。我的目标是避免重复的self.present(error:)代码:

_ = FBSDKGraphRequest.emailRequest().start() { (result: Result<Any>) in

    switch result {
    case .success (let value as [ String : Any ]):
        ...
        if let email = value["email"] as? String {
            ...
        }
        else {
            self.present(error: Error(.facebookOther))
        }

    default:
        self.present(error: Error(.facebookOther))
    }
}

1 个答案:

答案 0 :(得分:1)

我不确定您可以使用switch消除重复并可以选择绑定email,但是可以使用if

if case .success(let value as [String : Any]) = result, let email = value["email"] as? String {
    print("email: \(email)")
} else {
    self.present(error: Error(.facebookOther))
}

使用switch最好的办法是通过添加where子句来避免重复,但是您错过了email的可选绑定:

switch result {
case .success (let value as [ String : Any ]) where value["email"] is String:
    let email = value["email"] as! String
    print("email: \(email)")
default:
    self.present(error: Error(.facebookOther))
}