简体   繁体   English

如何在 switch 语句中将类型转换为枚举中的变量?

[英]How to I cast a type to a variable in an enum within a switch statement?

switch error {
case Project.Client.LoadError.operationFailed(let error2):
    switch error2 {
    case Project.Client.APIClientError.invalidStatusCode(let message, _):
        guard message != nil, message == "error" else {
            return refresh()
        }
        delegate?.error(invalidScript)
    default:
        refresh()
    }
default:
    refresh()
}

Here is my current code.这是我当前的代码。 This works but I feel there is a better way to do this.这行得通,但我觉得有更好的方法可以做到这一点。 How can I make error2 NOT go through another switch statement and just cast it as an invalidStatusCode that I can use?如何通过另一个switch语句使error2 NOT go 并将其转换为我可以使用的invalidStatusCode

Or, what terms can I search up to better understand what is happening here/understand what to look up myself for the answer?或者,我可以搜索哪些术语以更好地了解这里发生的事情/了解要查找自己的答案的内容? As I might not be fully understanding switch statements as casting type.因为我可能没有完全理解 switch 语句作为转换类型。

Thank you in advance.先感谢您。

Pattern matching of enums with associated values is composable, so you can do this:枚举与关联值的模式匹配是可组合的,因此您可以这样做:

switch error {
case Project.Client.LoadError.operationFailed(Project.Client.APIClientError.invalidStatusCode("error" , _)):
    delegate?.error(invalidScript)
default:
    refresh()
}

You might notice that this is a bit hard to read because of how long these fully-qualified type-names are.您可能会注意到,由于这些完全限定类型名称的长度,这有点难以阅读。

I suspect the type of error is the general Error , but in other cases, if the type of error is already-known to be Project.Client.LoadError , then you can just use .operationFailed (leaving the type to be inferred from context).我怀疑error类型是一般Error ,但在其他情况下,如果已知error类型是Project.Client.LoadError ,那么您可以只使用.operationFailed (让类型从上下文中推断出来) . And if .operationFailed 's associated type is known to have type Project.Client.APIClientError , you can just use .invalidStatusCode .如果已知.operationFailed的关联类型具有类型Project.Client.APIClientError ,则您可以只使用.invalidStatusCode

If not, you can use some local type-aliases can help with that:如果没有,您可以使用一些本地类型别名来帮助解决这个问题:

typealias LoadError = Project.Client.LoadError
typealias APIClientError = Project.Client.APIClientError

switch error {
case LoadError.operationFailed(APIClientError.invalidStatusCode("error", _)):
    delegate?.error(invalidScript)
default:
    refresh()
}

Since you are just drilling down to one case for both switches, you don't need any switches at all.由于您只是深入了解两个开关的一种情况,因此您根本不需要任何开关。 You can use if case instead.您可以改用if case To generalize, suppose we have this:概括地说,假设我们有这个:

enum Outer {
    case inner(Inner)
    case other
}

enum Inner {
    case message(String)
    case other
}

Now suppose subject might be an Outer.现在假设subject可能是一个 Outer。 Then to determine that this is an Outer's .inner case whose Inner value is .message and that message's value is "howdy", we can say:然后确定这是一个 Outer 的.inner案例,其内部值为.message并且该消息的值为“howdy”,我们可以说:

if case Outer.inner(let inner) = subject, 
    case Inner.message(let message) = inner, 
    message == "howdy" {

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM