【问题标题】:How to exit a function scope from inner function using Swift?如何使用 Swift 从内部函数中退出函数范围?
【发布时间】:2017-11-12 16:51:31
【问题描述】:

return 可以退出当前函数的作用域,但是否也可以退出调用内部函数的外部函数作用域?

func innerFunction() {
  guard 1 == 2 else {
    // exit scope of innerFunction and outerFunction
  }
}

func outerFunction() {
  innerFunction()
  print("should be unreachable")
}

可能有一种方法使用我们可以检查的内部函数的返回值:

func innerFunction() -> Bool {
  guard 1 == 2 else {
    return false
  }
  return true
}

func outerFunction() {
  guard innerFunction() else {
    return
  }
  print("should be unreachable")
}

这种方法的问题在于,如果函数变得更加复杂并且您必须一遍又一遍地使用它们,它会很快使您的代码变得混乱。

考虑将此方法应用于XCTest。它看起来像这样:

func testFoobar() {
  guard let unwrappedObject = helperFunction() else {
    XCTFail("A failure message that can change with each helperFunction call")
    return
  }
  print("should be unreachable when helperFunction already failed")
}

我想要类似的东西:

func testFoobar() {
  let unwrappedObject = helperFunction()
  print("should be unreachable when helperFunction already failed")
}

【问题讨论】:

标签: swift function scope


【解决方案1】:

这基本上是 Swift 的错误处理所做的:

func outer() throws
{
    try inner()
    print("Unreachable")
}

struct DoNotContinue : Error {}

func inner() throws
{
    throw DoNotContinue()
}

do { try outer() }
catch _ { print("Skipped the unreachable") }

当然,请注意,调用者仍然对此有控制权:它可以自己捕获抛出的错误,而不仅仅是退出。

这种方法的问题是它会使您的代码混乱

允许被调用者直接退出调用者有一个更严重的问题,那就是控制流非常很快变得难以理解。想象一下,你有几层这样的。阅读顶层函数,你不再清楚会发生什么。您必须自己递归到每个被调用者的被调用者,以确保原始代码将继续其进程。

【讨论】:

  • 如果他们不希望人们称他们为异常,他们就不应该使用糟糕的try-catch 语法。 :)
  • 我同意选择围绕 Swift 错误的关键字是不幸的,但我们不要传播误解。你知道他们怎么说“当在罗马……”,对吧?在使用它的编程语言的上下文中,我还将% 发音为“模”,尽管历史和常识说它通常是“百分比”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-25
  • 1970-01-01
  • 2021-10-30
  • 2016-10-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多