“消失”的零:为什么Int不存储前导零以及如何应对?
\n\n您是否曾尝试在屏幕上显示数字007,却只得到7?是不是很熟悉?欢迎加入Swift开发者俱乐部,他们迟早都会遇到这个问题:“如何为Int添加前导零?”
这个问题在Stack Overflow上获得了数千次浏览,这并不奇怪。看似简单的任务——将订单号显示为“001234”而不是“1234”,或将时间显示为“09:05”而不是“9:5”。但Swift作为一种强类型语言,区分了“数字”和“其字符串表示形式”的概念。Int是一个数学实体。007对它来说只是7。前导零在初始化时就会丢失。
在本文中,我们将分析所有主要方法来解决这个问题。您将学习如何正确格式化整数,如何针对不同任务选择合适的方法,以及如何避免性能陷阱。我们将从简单的字符串掩码开始,一直讲到Foundation中强大的NumberFormatter。开始吧!
为什么Int不能存储“001”?简要说明
\n\n在深入代码之前,让我们先了解现象的本质。Swift中的Int是一个64位(在旧设备上是32位)有符号整数。其内部表示是二进制代码。左边的零没有数学意义。
let number = 007 // 错误?不!\nprint(number) // 输出:7\n\nSwift编译器甚至不允许您在代码中编写007(除非是八进制字面量,但那里有前缀0o)。结论:前导零是格式化问题,而不是数据存储问题。我们在表示层(UI、日志记录、导出)解决这个问题。
方法1:经典方法——String(format:)
\n\nStack Overflow上最流行的答案是使用String(format:)函数,该函数继承自Objective-C(通过NSString桥接)。这是一种快速且简洁的方法。
示例:添加3个前导零
\n\nlet number = 7\nlet formatted = String(format: "%04d", number)\nprint(formatted) // "0007"\n\n说明符%04d的含义:
- \n
%— 说明符的开始; \n 0— 用零填充空位,而不是空格; \n 4— 最小字段宽度(4个字符); \n d— 十进制整数(Int)。 \n
如果数字超过4个字符(例如12345),格式化不会截断它——您将得到“12345”。
\n\n优点和缺点
\n- \n
- 优点:简单、快速、一行代码。适用于所有Swift版本。 \n
- 缺点:底层使用
NSString,可能比纯Swift解决方案稍慢。需要记住C风格的格式化语法。不支持本地化(不考虑千位分隔符,如果需要的话)。 \n
何时使用:用于简单情况:日志、调试、输出ID,当不需要本地化时。
\n\n方法2:纯Swift——String(repeating:count:) + 后缀
\n\n如果您想避免Objective-C桥接并用“纯”Swift编写,可以手动实现。这是理解字符串的一个很好的练习。
\n\nextension Int {\n func leadingZeros(_ totalDigits: Int) -> String {\n let stringValue = String(self)\n let zerosCount = max(0, totalDigits - stringValue.count)\n return String(repeating: "0", count: zerosCount) + stringValue\n }\n}\n\nlet number = 42\nprint(number.leadingZeros(5)) // "00042"\n\n它是如何工作的?
\n- \n
- 将Int转换为字符串。 \n
- 计算需要添加多少个零:
totalDigits - length。如果