2016-08-15 65 views
6

我对代码块或'范围'的定义感到困惑。苹果公司的警告说:这是另一个警卫声明块...如果Swift'guard'语句必须退出范围,范围的定义是什么?

“必须传输控制以退出出现警戒语句的代码块”。

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

根据我目前的 '范围' 的理解,代码

if y == 2 {....} 

创建一个新的范围,即在{}。考虑到这个假设,后卫只会逃避这个范围。但事实并非如此。在这个例子中,守卫从其被放置的功能中逃脱出来,而不管它是否被埋在if子句中。

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

+0

要求是else子句离开当前范围。 'return'通过留下当然会留下当前范围的整个函数来满足要求。没有必要在else子句中使用'return'。其他的东西会起作用,比如“继续”。 – vacawama

回答

14

完全可以做你的设想,它恰好不是那个特定的代码所做的。 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

+0

明白了。谢谢! –

+0

我忘了提及*为什么*你需要一个标签来打破'if'。想要有条件地从循环中断开是很常见的。这肯定比想要从'if'中断''更普遍。因此,'if'语句中的'break'默认打破最接近的循环范围。其他行为来自明确指定标签。 – Alexander

+0

@Alexander - 只是想确认一下 - 在封闭环境中使用时它是如何工作的?它是否退出关闭或实现关闭的功能? –

0

你错误地解释了文档所说的内容。警戒声明本身不会退出任何范围。你必须在守卫声明中写出一些声明,该声明退出包含守卫声明的范围。

return将退出范围。在循环中,中断或继续将退出范围。在很多情况下,goto将退出该站点。没有具体的语句来退出if语句的范围,因此您需要goto语句或退出循环或包含guard语句的函数的内容。

+1

'没有具体的语句来退出if语句的范围'False,'break'可以。 '所以你需要一个goto语句'Swift没有'goto',但它不是必须的,无论如何,因为'break'本质上是一样的。 – Alexander

2

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

说明退出代码块在文档中是最准确的。

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

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