You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中优雅标记输入错误的数据结构方案咨询

问题

我正在开发一款工具,它接收包括部分文件在内的特定输入集,对输入进行解析、错误检查,若无错误则执行实际操作。
该工具需验证规范中预定义的约20种带有特定错误信息的输入错误。
作为Swift新手,我原本可以不使用任何数据结构实现这些错误检查,但对枚举的用法很感兴趣,想探索在此场景下使用枚举是否合理。

我计划编写如下代码:

enum ErrorCheck {
     case incorrectFilePathProvided (code: Int, description: String)
     case inputFileIsMissingVersionNumber (code: Int, description: String)
     ....
}

let errorIncorrectFilePathProvided = ErrorCheck.inputFileNotProvided(1, "User has provided incorrect input file")
....

static func validateInputParams(param1: String, param2: NSDictionary) -> NSArray {
     var result: NSMutableArray = []
     if !param1.hasPrefix("/Application") {
        result.add([ErrorCheck.errorIncorrectInputFilePathProvided.code : ErrorCheck.errorIncorrectInputFilePathProvided.description])
     }
     
     if !param2["specificKey"] {
             result.add([ErrorCheck.errorIncorrectInputFilePathProvided.code : ErrorCheck.errorIncorrectInputFilePathProvided.description])
      }
} 

请问该方案是否合理?或者有无更符合Swift风格的实现方式?

回答

用枚举管理这类预定义的输入错误完全合理,甚至是非常合适的选择,但你当前的写法还有不少可以优化的地方,能更贴合Swift的原生风格:

1. 让枚举实现Error协议

Swift原生的Error协议是处理错误的标准范式,让你的枚举遵循它,能更好地兼容Swift的错误处理机制(比如throw、do-catch)。同时可以把错误码、描述做成枚举的计算属性,避免每个case重复携带关联值,让代码更整洁:

enum InputValidationError: Error {
    case incorrectFilePathProvided
    case inputFileIsMissingVersionNumber
    // 补充其他约20种错误case
    
    // 计算属性返回对应错误码
    var code: Int {
        switch self {
        case .incorrectFilePathProvided: return 1
        case .inputFileIsMissingVersionNumber: return 2
        // 为每个case匹配对应的错误码
        }
    }
    
    // 计算属性返回错误描述
    var description: String {
        switch self {
        case .incorrectFilePathProvided:
            return "User has provided incorrect input file"
        case .inputFileIsMissingVersionNumber:
            return "Input file does not contain a version number"
        // 为每个case匹配对应的描述
        }
    }
}

这种写法的好处是,所有错误的码和描述都集中管理,不会出现关联值拼写错误或不匹配的问题,后续维护也更方便。

2. 替换Objective-C类型为Swift原生集合

你代码里用的NSArray、NSMutableArray、NSDictionary都是Objective-C的类型,Swift有更安全的原生集合类型,比如[InputValidationError]、[String: Any],类型更明确,还能避免隐式转换带来的问题:

static func validateInputParams(param1: String, param2: [String: Any]) -> [InputValidationError] {
    var errors: [InputValidationError] = []
    
    if !param1.hasPrefix("/Application") {
        errors.append(.incorrectFilePathProvided)
    }
    
    // 注意这里要匹配正确的错误case,你原代码里写错了
    if param2["specificKey"] == nil {
        errors.append(.inputFileIsMissingVersionNumber)
    }
    
    return errors
}

如果需要把错误转换成字典格式对外输出,可以给枚举加个扩展方法:

extension InputValidationError {
    func toDictionary() -> [String: Any] {
        return ["code": code, "description": description]
    }
}

// 使用示例
let validationErrors = validateInputParams(param1: "testPath", param2: [:])
let errorDicts = validationErrors.map { $0.toDictionary() }

3. 扩展性优势

后续如果需要新增错误类型,只需要在枚举里添加新的case,然后补充code和description的switch分支即可,维护成本极低,这正是枚举处理这类场景的核心优势。

总的来说,你的思路方向完全正确,优化后的写法更符合Swift类型安全、简洁的风格,也能更好地融入Swift的错误处理体系。

内容的提问来源于stack exchange,提问作者agent.smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 00:50:02