nil、空字符串和数字0是不同状态。把所有可选值都换成默认值,可能抹掉未输入与明确输入0的区别。先决定缺失应该使用正常默认值,还是保留为独立状态。
原理与设计判断
Optional用some与none表示存在与否。局部条件处理选if let,提前返回选guard let,有合理默认值时选??。可选链遇到缺失值会得到nil;强制解包在nil时中止,不适合预期内的输入失败。 一手资料
复现代码
quantity用不同enum表示缺失、无效与有效数量。六个用例是nil、空字符串、cat、-1、0、7。默认值函数记录??调用次数,并单独比较空字符串与缺失字符串的count。
这个独立示例已于 2026-10-23 使用 Apple Swift 6.4,以 Swift 6 语言模式在 arm64 macOS 目标环境运行。不需要网络或额外软件包。
请在下载文件的文件夹中运行。检查不通过时,precondition 会终止程序。请勿使用 -Ounchecked,因为它会移除这些检查。
swift -swift-version 6 swift-optional-enum-unwrapping.swift
enum Quantity: Equatable { case missing, invalid, value(Int) }
func quantity(_ raw: String?) -> Quantity {
guard let raw else { return .missing }
guard let value = Int(raw), value >= 0 else { return .invalid }
return .value(value)
}
let cases: [(String?, Quantity)] = [
(nil, .missing), ("", .invalid), ("cat", .invalid),
("-1", .invalid), ("0", .value(0)), ("7", .value(7))
]
for (raw, expected) in cases { precondition(quantity(raw) == expected) }
var fallbackCalls = 0
@MainActor func fallback() -> Int { fallbackCalls += 1; return 99 }
let present: Int? = 0
let absent: Int? = nil
precondition((present ?? fallback()) == 0 && fallbackCalls == 0)
precondition((absent ?? fallback()) == 99 && fallbackCalls == 1)
let empty: String? = ""
let missing: String? = nil
precondition(empty?.count == 0 && missing?.count == nil)
print("inputs=6 missing=1 invalid=3 valid=2 fallback-calls=1 empty-count=0 missing-count=nil")
运行结果与解读
inputs=6 missing=1 invalid=3 valid=2 fallback-calls=1 empty-count=0 missing-count=nil
结果区分出一个缺失值、三个无效输入和两个有效值。some(0)不执行默认值函数,none才执行一次。空字符串的count是0,缺失字符串的链式访问结果则是nil。类似零的值不代表不存在。
适用范围与限制
这是拒绝负数的数量验证器,不是通用数字输入策略。空白、小数、地区格式和上限都需按需求补充。String!也是会在需要的上下文中隐式解包的可选声明,不是每次使用都无条件强制解包。
接下来要确认的事
先决定缺失与无效输入是否显示不同提示,并与服务器契约一致。如果调用方需要更细的失败原因,请用throws或Result保留信息,而不是默默覆盖成默认值。
来源与验证
- The Swift Programming Language: The BasicsSwift.org · 官方文档 · 核查 2026年10月23日依据: 实现契约与说明的依据。运行输出另由本文所附实验确认。

