我对代码块或'作用域'的定义感到困惑。Apple for guard文档是这样说的:guard语句的else块…
"必须转移控制以退出出现guard语句的代码块。"
其他在线资源说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()
根据我目前对'scope'的理解,代码
if y == 2 {....}
创建一个新的作用域,即在{}之间。在这个假设下,警卫只会逃离这个范围。但事实并非如此。此实例中的Guard将从它所在的函数中转义,无论它是否隐藏在if子句中。
我完全误解了'scope'的意思吗?作用域是指方法中包含的代码吗?如果是这样,If语句中存在的"空间"的正确术语是什么?
完全有可能实现您的设想,只是碰巧不是特定代码所做的。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的回答:
guard
强制您使用控制转移语句退出作用域。有4种可供您选择:
-
return
和throw
同时退出函数/方法 -
continue
可以在循环内使用(while
/for
/repeat-while
) -
break
可以在循环(while
/for
/repeat-while
)中使用,以退出直接作用域。指定要中断的标签将允许你一次退出多个作用域(例如,跳出嵌套循环结构)。当使用标签时,break
也可以在if
范围内使用。
此外,您可以通过调用返回Never
的函数来退出作用域,例如fatalError
。
这个约束实际上是一件好事,这也是您可能想要使用guard
而不是if
的原因。它的意思是:
它使您避免检查先决条件,但随后意外地通过,就好像您没有检查过一样
它让条件绑定更好地工作。举个例子:
guard let nonOptional = anOptional() else { return } usesANonOptional(nonOptional)
usesANonOptional
只有在传递了非可选参数时才安全。如果anOptional
返回nil
,则守卫将失败,并且将确保您不可能调用usesANonOptional
。这意味着nonOptional
是已知的非可选的,并且会自动为您打开包装。
你对术语范围的理解是完全正确的。它基本上是两个(平衡的)大括号之间的空间。
文档中退出代码块的描述是最准确的。
要退出guard
语句,可以使用控制转移语句return
、break
、continue
或throw
。
-
return
和throw
退出整个函数或方法。 -
continue
和break
退出当前作用域(例如switch
、for
或while
)。
你误解了医生说的话。guard语句本身不退出任何作用域。你必须在guard语句内写一些语句,退出包含该guard语句的作用域。
return将退出作用域。在循环中,break或continue将退出作用域。在许多情况下,goto将退出停止。没有特定的语句来退出if语句的作用域,因此您需要一个goto语句或其他语句来退出循环或包含guard语句的函数。