如果Swift 'guard'语句必须退出作用域,那么作用域的定义是什么?

wgx48brx  于 2023-01-25  发布在  Swift
关注(0)|答案(3)|浏览(106)

我对代码块或“作用域”的定义感到困惑。苹果的guard文档是这样说的:保护语句的else块...
“必须转移控制才能退出显示guard语句的代码块。”
其他的online sources说guard语句必须退出它所在的“作用域”。
下面的代码示例:

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()

根据我目前对“作用域”的理解

if y == 2 {....}

创建了一个新的作用域,即between { }。假定这样,guard只会转义那个作用域。但事实并非如此。在这个示例中,Guard会从它所在的函数中转义,而不管它是否隐藏在if子句中。
我是不是完全误解了“作用域”的意思?作用域是指包含在方法中的代码吗?如果是这样,if语句中的“空格”的正确术语是什么?

z0qdvdin

z0qdvdin1#

你完全可以按照你的设想去做,只是碰巧不是那个特定的代码所做的。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)来退出作用域。
这个约束实际上是一件好事,这也是为什么你可能想使用guard而不仅仅是if的原因,它意味着:
1.它使你无法检查一个前提条件,但却意外地通过,好像你没有
1.它让条件绑定工作得更好,举个例子:

guard let nonOptional = anOptional() else { return }
usesANonOptional(nonOptional)

usesANonOptional只有在传递了一个non-optional的情况下才能安全调用。如果anOptional返回nil,guard将失败,并确保您不可能调用usesANonOptional。这意味着nonOptional已知为non-optional,并会自动为您展开。

iaqfqrcu

iaqfqrcu2#

你对作用域这个术语的理解是绝对正确的。基本上它是两个(平衡的)大括号之间的空格。
文档中的描述 * 退出代码块 * 是最准确的。
要退出guard语句,可以使用 * 控制转移 * 语句returnbreakcontinuethrow

  • returnthrow退出整个函数或方法。
  • continuebreak退出当前作用域(例如switchforwhile)。
3phpmpom

3phpmpom3#

你误解了文档的意思。guard语句本身并不存在于任何作用域中。你必须在guard语句中写一些语句,这些语句存在于包含guard语句的作用域中。
return将退出作用域。在循环中,break或continue将退出作用域。在许多情况下,后藤将退出stop。没有特定的语句可以退出if语句的作用域,因此您需要一个goto语句或其他语句来退出包含guard语句的循环或函数。

相关问题