You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Swift中for-in循环失效排查:错误处理致仅打印首个尝试值

问题分析与修复方案

Hey there! I see exactly what's going on here—your loop stops after the first password attempt because of how you're handling errors. Let's break down the issues and fix them step by step.

核心问题

  1. 错误抛出时机过早:在你的OpenSafe函数里,只要第一个尝试的密码不匹配,你立刻抛出SafeError.wrongCode。一旦抛出错误,函数会立即终止执行,后面的循环迭代根本没机会运行,这就是为什么只打印第一个密码。
  2. 尝试次数检查逻辑位置错误:你把guard triedCodes.count <= maximumTries放在了循环结束后,这意味着即使传入的密码数组长度超过了最大尝试次数,代码还是会先遍历完所有密码(如果没提前抛错的话),这显然不符合逻辑。
  3. 找到正确密码后未终止流程:就算某次尝试的密码正确,你的代码会继续循环尝试剩下的密码,而不是直接打开保险箱并结束流程。

修复后的代码

enum SafeError: Error { 
    case wrongCode 
    case tooMuchTries 
    case safeIsOpen 
}

struct Safe {
    var safeIsclosed: Bool
    var code: String
    var maximumTries: Int
    
    mutating func openSafe(triedCodes: [String]) throws {
        // 先检查保险箱是否已经打开
        guard safeIsclosed else { throw SafeError.safeIsOpen }
        // 先检查尝试次数是否超过最大值
        guard triedCodes.count <= maximumTries else { throw SafeError.tooMuchTries }
        
        for triedCode in triedCodes {
            print("Try \(triedCode)")
            // 如果密码正确,打开保险箱并终止函数
            if triedCode == code {
                safeIsclosed = false
                print("Password was correct")
                return
            }
        }
        // 所有尝试都失败,抛出错误
        throw SafeError.wrongCode
    }
}

var safe = Safe(safeIsclosed: true, code: "WD1146", maximumTries: 5)
do {
    try safe.openSafe(triedCodes: ["DD377789", "123456", "WD1146", "112378AADD", "DDFG4567"])
} catch SafeError.safeIsOpen {
    print("Safe is already open")
} catch SafeError.tooMuchTries {
    print("You've exceeded the maximum number of allowed tries")
} catch SafeError.wrongCode {
    print("Wrong Password - all attempts failed")
} catch {
    print("Unexpected error: \(error)")
}

关键修改说明

  • 提前检查尝试次数:在循环开始前就验证传入的密码数组长度是否超过maximumTries,避免无效的遍历。
  • 调整错误抛出逻辑:不再在每次错误尝试时立即抛错,而是遍历完所有传入的密码后,如果都不正确才抛出wrongCode
  • 找到正确密码后立即终止:一旦匹配到正确密码,就修改safeIsclosed状态,打印成功信息,然后用return终止函数,停止后续循环。
  • 函数名规范:把OpenSafe改成了openSafe,符合Swift的小驼峰命名规范。

现在运行这段代码,你会看到所有密码尝试都会被打印出来,直到找到正确的那个为止,完全符合你的预期!

内容的提问来源于stack exchange,提问作者Christoph Drescher

火山引擎 最新活动