如何在场景转换尝试中处理 "no scene"?

How to handle "no scene" in a scene transition attempt?

在应该加载场景的按钮中,我正在尝试学习使用 guard 语句,但对它在四个 "escapes" 中的每一个的作用感到非常困惑。不知道怎么处理没有场景的情况

这里使用哪个是正确的: continuereturnbreakthrow?

还有……为什么?

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

    for touch: AnyObject in touches {

        let location = touch.location(in: self)

        if self.rr.contains(location) {
            guard let nextScene = goesTo
                else {print(" No such Scene ")
                continue } // continue, return, break, throw !!!!????
            loadScene(withIdentifier: nextScene)
            }
        }
    }

我认为场景不适合 guard 语句,因为你有很多情况在循环中,你想避免一些情况!首先我们需要知道什么时候应该使用 guard 语句。是的,它可以帮助您处理错误,但这并不意味着您应该随时随地使用它!

Why guard and when to use them and not to use them:

The Guard Statement in Swift

更新

我希望这会澄清你的问题

when you are using break

let array: [Int?] = [3, 7, nil, 12, 40]

for arrayValue in array {

    guard let value = arrayValue else {
        print("No Value")
        break
    }

    print(value)
}

输出

3

7

无价值

when you are using continue

let array: [Int?] = [3, 7, nil, 12, 40]

for arrayValue in array {

    guard let value = arrayValue else {
        print("No Value")
        continue
    }

    print(value)

输出

3

7

无价值

12

40

Return 将关闭该函数,并且在这种情况下与 break 的行为相同。现在请根据您的需要做出决定!如果您认为在没有场景条件时可以中断它,那么就中断,或者如果您想跳过它,那么只需继续跳过那个确切的场景。我希望你明白我的意思

在您的特定示例中,所有三个都将做基本相同的事情。但是在 touchesEnded 中使用循环很奇怪,因为这是最后一次触摸,而且只有一次触摸,除非你正在进行多手势操作。

如果您要在 for 循环下添加其他代码,那么您可能会破坏程序,因为您没有处理 guard 语句。如果您想忽略没有场景的其余功能,使用 return 将是理想的选择。

// Break works with named labels, which can be used with while, do, and for.
// Why? Break exits loops because it's a command that redirects the
// execution of code, similar to goto in C.

outerLabel: do {
    if 0==0 { print("numbers are fun and,") }
    if 0==2 { break outerLabel } // NOTE: the label is required for
                                 // `break` when not in `while` or `switch`
    print("zero was not equal to two")
}

// Continue breaks from the current iteration (whatever value `i` is at),
// but then restarts the loop with the next value (0..1..2..3...)
for i in 1...10 {
  print(" Hello ")
  if 0==0 { continue }
  print(" Worlllddd ") // We will see 10 hellos but no worlds.
}


// Here is the example with guard
stuff: do {
  guard 0 == 2 else { break stuff } // Again, the label here is required for break.
  print(" zero is equal to two " ) // Doesn't print, lol...
}

moreStuff: for i in 1...10 {
  print(" is zero equal to two? ")
  guard 0 == 0 else { continue } // Label is optional for continue.
  print(" zero is equal to zero " ) // Does print.
}

// Here is how we use return with guard, and the print maybe explains why:
func ohLookAFunc() {
  guard 0 == 0 else {
    print(" Math and numbers as we know it are over!! ")
    return
    // ... now we xit from this crazy Func where 0 is not 0
    // You can handle this exception in any-way you see fit.
    // So if your scene doesn't exist, or if 0 is == 2, then 
    // it's up to you to figure out what to do in such disastrous
    // situations ;)
  }
  print(" Now we continue the function safe in the fact that 0 is still equal to 0")
}

没有"best"使用这些语句。这仅取决于 you 在做什么以及 you 设置了什么逻辑。

没有人能告诉您如果找不到场景该怎么办,除了忽略输入(return 来自 touchesEnded() 什么都不做)。

或者,您可以将其设置为确保始终显示正确的场景。这部分由您负责 :) 如果没有更多代码,我们无法帮助您确保这一点。

如果您处于 for 循环中,则 continue 将移至下一次迭代,而 break 将退出 for 循环。 Return 将始终退出当前函数。

在这种情况下,您可能希望将 guard 语句放在 for 循环之前并退出 touchesEnded,因为我假设 goesTo 设置在别处。

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard let nextScene = goesTo else {
        print(" No such Scene ")
        return // exit touchesEnded since goesTo is not defined 
    }

    for touch: AnyObject in touches {
        let location = touch.location(in: self)

        if self.rr.contains(location) {
            loadScene(withIdentifier: nextScene)
        }
    }
}