Swift中Int的前导零:从混乱到有序

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

“消失”的零:为什么Int不存储前导零以及如何应对?

\n\n

您是否曾尝试在屏幕上显示数字007,却只得到7?是不是很熟悉?欢迎加入Swift开发者俱乐部,他们迟早都会遇到这个问题:“如何为Int添加前导零?”

\n\n

这个问题在Stack Overflow上获得了数千次浏览,这并不奇怪。看似简单的任务——将订单号显示为“001234”而不是“1234”,或将时间显示为“09:05”而不是“9:5”。但Swift作为一种强类型语言,区分了“数字”和“其字符串表示形式”的概念。Int是一个数学实体。007对它来说只是7。前导零在初始化时就会丢失。

\n\n

在本文中,我们将分析所有主要方法来解决这个问题。您将学习如何正确格式化整数,如何针对不同任务选择合适的方法,以及如何避免性能陷阱。我们将从简单的字符串掩码开始,一直讲到Foundation中强大的NumberFormatter。开始吧!

\n\n

为什么Int不能存储“001”?简要说明

\n\n

在深入代码之前,让我们先了解现象的本质。Swift中的Int是一个64位(在旧设备上是32位)有符号整数。其内部表示是二进制代码。左边的零没有数学意义。

\n\n
let number = 007 // 错误?不!\nprint(number) // 输出:7
\n\n

Swift编译器甚至不允许您在代码中编写007(除非是八进制字面量,但那里有前缀0o)。结论:前导零是格式化问题,而不是数据存储问题。我们在表示层(UI、日志记录、导出)解决这个问题。

\n\n

方法1:经典方法——String(format:)

\n\n

Stack Overflow上最流行的答案是使用String(format:)函数,该函数继承自Objective-C(通过NSString桥接)。这是一种快速且简洁的方法。

\n\n

示例:添加3个前导零

\n\n
let number = 7\nlet formatted = String(format: "%04d", number)\nprint(formatted) // "0007"
\n\n

说明符%04d的含义:

\n
    \n
  • % — 说明符的开始;
  • \n
  • 0 — 用零填充空位,而不是空格;
  • \n
  • 4 — 最小字段宽度(4个字符);
  • \n
  • d — 十进制整数(Int)。
  • \n
\n\n

如果数字超过4个字符(例如12345),格式化不会截断它——您将得到“12345”。

\n\n

优点和缺点

\n
    \n
  • 优点:简单、快速、一行代码。适用于所有Swift版本。
  • \n
  • 缺点:底层使用NSString,可能比纯Swift解决方案稍慢。需要记住C风格的格式化语法。不支持本地化(不考虑千位分隔符,如果需要的话)。
  • \n
\n\n

何时使用:用于简单情况:日志、调试、输出ID,当不需要本地化时。

\n\n

方法2:纯Swift——String(repeating:count:) + 后缀

\n\n

如果您想避免Objective-C桥接并用“纯”Swift编写,可以手动实现。这是理解字符串的一个很好的练习。

\n\n
extension 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
  1. 将Int转换为字符串。
  2. \n
  3. 计算需要添加多少个零:totalDigits - length。如果

博客

书籍推荐