假设我有一个枚举定义如下:
enum Response {
case Result(String, Int)
case Error(String)
}
然后,我得到了这样的答复:
let resp: Response = // ...
假设我想编写一个switch语句并以与Result和Error案例相同的方式处理,并将同名的变量绑定到它们包含的String
。我怎样才能做到这一点?从概念上讲,类似于此:
switch resp {
case let .Result(str, _), let .Error(str):
println("Found: \(str)")
}
其中str
绑定两次,_
表示我对Int
携带的Result
值不感兴趣。
到目前为止,我能找到的最接近的事情是声明一个这样的内联函数,然后调用它:
func processRespString(str: String) {
println("Found \(str)")
}
switch resp {
case let .Result(str, _): processRespString(str)
case let .Error(str): processRespString(str)
}
有更好的方法吗?
答案 0 :(得分:3)
已被接受的Swift evolution Proposal SE-0043使用Swift 3解决了此问题。
enum Response {
case result(String, Int)
case error(String)
}
let resp = Response.error("Some text")
switch resp {
case let .result(str, _), let .error(str):
print("Found: \(str)") // prints Found: Some text
}
使用Swift 2,之前的Playground代码会生成错误:case labels with multiple patterns cannot declare variables
。但是,使用Swift 3,它不会产生任何错误并且具有预期的行为。
答案 1 :(得分:2)
不,但是如果你想访问Response的String值,无论它是.Result还是.Error,你都可以这样做:
enum Response {
case Result(String, Int)
case Error(String)
func Message() -> String {
switch self {
case let .Result(str, _):
return str
case let .Error(str):
return str
}
}
}
var resp: Response = .Error("Fault")
resp = .Result("Success",5)
println(resp.Message())
这样你就可以将枚举的逻辑保留在枚举本身内。
答案 2 :(得分:1)
最明显的方法是使用可选代替枚举来表示错误:
struct Response {
var string:String
var result: Int?
var isError: Bool { return result == nil }
}
如果您坚持使用枚举,可以将其与原始代码混合使用 -
// Auxiliary enum
enum IntResponse {
case Result(Int)
case Error()
}
struct FullResponse {
// Real properties
var string: String
var response: IntResponse
// Convenience property
var result: Int? {
switch(response) {
case let .Result(value): return value
case let .Error(): return nil
}
}
// Initializers for success and error
init(errorString:String) {
self.string = errorString
self.response = IntResponse.Error()
}
init(string:String, result:Int) {
self.string = string
self.response = IntResponse.Result(result)
}
}
// An example usage
let error = FullResponse(errorString: "some error")
let success = FullResponse(string: "success", result: 10)
func do_something(response: FullResponse) {
println(response.string) // works for any of the cases
}