【问题标题】:If the Swift 'guard' statement must exit scope, what is the definition of scope?如果 Swift 'guard' 语句必须退出作用域,作用域的定义是什么?
【发布时间】:2016-12-21 20:51:22
【问题描述】:

我对代码块或“范围”的定义感到困惑。苹果守卫文档这样说:守卫语句的 else 块......

“必须转移控制权才能退出出现保护语句的代码块。”

其他online sources 说保护语句必须退出它存在的“范围”。

所以以下面的示例代码为例:

func testGuardControlFlow () {

let x = 2
let y = 2

    func embededFunc () {

        if y == 2 {

            guard x == 1 else {
                print("oops, number is not 1")
                return
            }

            print ("from in embededFunc")

        }

        print ("I still want this to print even if x != 1")
    }

    embededFunc()
    print("Great, return still allows this to be printed.")

}

testGuardControlFlow()

根据我目前对'scope'的理解,代码

if y == 2 {....}

创建一个新范围,即在 { } 之间。考虑到这个假设,guard 只会逃避这个范围。但事实并非如此。在这种情况下,Guard 会从它所在的函数中逃脱,而不管它是否被埋在 if 子句中。

我是否完全误解了“范围”的含义?范围是指方法中包含的代码吗?如果是这样,if 语句中存在的“空间”的正确术语是什么?

【问题讨论】:

  • 要求else子句离开当前作用域。 return 通过离开整个函数来满足要求,这肯定会离开当前范围。不必在 else 子句中使用 return。其他的也可以,比如continue

标签: swift scope


【解决方案1】:

完全有可能按照您的设想去做,只是碰巧不是特定代码所做的。 return 总是退出一个方法,而不是本地范围。做你想做的事,你可以使用标签和break

func testGuardControlFlow () {

    let x = 2
    let y = 2

    func embededFunc () {

        breakLabel:
        if y == 2 {

            guard x == 1 else {
                print("oops, number is not 1")
                break breakLabel
            }

            print ("from in embededFunc")

        }

        print ("I still want this to print even if x != 1")
    }

    embededFunc()
    print("Great, return still allows this to be printed.")

}

testGuardControlFlow()

添加到vadian's answer

guard 使用控制转移语句强制您退出范围。您可以使用 4 个:

  • returnthrow 都退出函数/方法
  • continue 可以在循环中使用 (while/for/repeat-while)
  • break 可以在循环中使用 (while/for/repeat-while) 以退出直接作用域。指定要中断的标签将允许您一次退出多个范围(例如,中断嵌套循环结构)。使用标签时,break 也可以在 if 范围内使用。

此外,您可以通过调用返回Never 的函数来退出作用域,例如fatalError

【讨论】:

  • 我忘了说为什么你需要一个标签来打破if。想要有条件地从循环中中断是很常见的。这肯定比想从if 发送break 要普遍得多。因此,if 语句中的break 默认打破最近的循环范围。其他行为来自明确指定标签。
  • @Alexander - 只是想确认一下 - 在闭包内使用时它是如何工作的?它是退出闭包还是退出实现闭包的函数?
  • @PoojaGaikwad 只是关闭。你会想到这个要求背后的原因:如果变量foo 的条件绑定失败,那么如果允许程序继续执行假定@ 的部分代码,程序应该做什么987654347@ 作为已定义的非零变量?将guard 视为将范围的其余部分放在“if let”块中,其“else”块会将您吐出超出范围的末尾。
  • @Alexander - 是的,谢谢.. 刚刚尝试了一个示例,按预期工作.. 似乎很明智 :)
【解决方案2】:

您对“范围”一词的理解是绝对正确的。基本上它是两个(平衡的)大括号之间的空间。

文档中退出代码块的描述是最准确的。

要退出guard 语句,您可以使用控制转移 语句returnbreakcontinuethrow

  • returnthrow 退出整个函数或方法。
  • continuebreak 退出当前范围(例如 switchforwhile)。

【讨论】:

    【解决方案3】:

    您误解了文档所说的内容。守卫语句本身不退出任何范围。您必须在退出包含保护语句的范围的保护语句内编写一些语句。

    return 将退出作用域。在循环中,break 或 continue 将退出范围。在许多情况下,goto 将退出停止。没有特定的语句可以退出 if 语句的范围,因此您需要 goto 语句或退出循环或包含保护语句的函数的东西。

    【讨论】:

    • There is no specific statement to exit the scope of an if statement 假,break 可以。 so you would need a goto statement Swift 没有goto,不过没必要,反正break 本质上是一样的。
    猜你喜欢
    • 2014-09-09
    • 2010-11-17
    • 1970-01-01
    • 2012-01-27
    • 2015-01-25
    • 2016-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多