0Pricing
Swift Academy · 课时

复数形式与 Stringsdict

处理不同语言的复数规则。

复数形式与 Stringsdict 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。

复数问题

英语有两种形式——1 item、2 items——因此开发人员经常编写 "\(n) item" + (n == 1 ? "" : "s")。这种做法会严重出错:阿拉伯语有六种复数类别,俄语有三种,日语只有一种。硬编码复数逻辑是一个随时可能出现的本地化错误。

// FRAGILE — only works for English
let n = 5
let bad = "\(n) item" + (n == 1 ? "" : "s")
print(bad)

复数类别

Unicode 定义了复数类别:零、单个、两个、少量、多量、其他。每种语言使用其中一部分。系统会根据区域设置规则为数字选择正确的类别,您无需自己编写这些规则。

// English uses: one, other
// Russian uses: one, few, many, other
// Japanese uses: other (only)
// You provide a variant string per category needed.

字符串目录中的复数变体

在字符串目录中,您可以将字符串标记为具有复数变体。随后,Xcode 允许您为每个类别提供文本。运行时,系统会根据插入的计数和用户的区域设置自动选择正确的变体。

// Catalog entry, key "message_count":
//   one:   "You have %lld message"
//   other: "You have %lld messages"
let count = 1
let text = String(localized: "You have \(count) messages")
print(text)

旧版 .stringsdict

在字符串目录出现之前,复数内容存放在 .stringsdict 文件中——这是一个将 key 映射到格式字符串及各类别变体的属性列表。您仍会在较旧的项目中看到这类文件,而且它们仍受到完整支持。

// Localizable.stringsdict (plist) structure:
// key: "items_count"
//   NSStringLocalizedFormatKey: "%#@items@"
//   items: NSStringPluralRuleType
//     one:   "%lld item"
//     other: "%lld items"

stringsdict 条目的结构

每个条目都有一个格式 key,用于引用一个或多个包裹在 %#@name@ 中的命名变量。每个变量都会声明其规则类型(NSStringPluralRuleType)、值类型说明符(%lld),以及每个复数类别对应的字符串。

// The %#@items@ token expands to the chosen
// plural variant. %lld is the integer placeholder
// substituted inside each variant string.
let n = 3
print(String(localized: "\(n) items selected"))

查找复数化字符串

从代码来看,调用位置与任何本地化字符串完全相同,只需插入计数即可。复数选择由框架内部完成,因此同一行 Swift 代码可以适用于每种语言。

func messagesLabel(_ count: Int) -> String {
    return String(localized: "You have \(count) messages")
}
print(messagesLabel(0))
print(messagesLabel(1))
print(messagesLabel(7))

为什么“一”不只是 1

一个常见错误是认为一类别只表示数字 1。在某些语言中,它涵盖所有以 1 结尾的数字(例如 21、31),而零可能有独立的类别,也可能没有。请始终为每个类别提供文本,并让规则决定使用哪一个。

// Russian: 1, 21, 31 -> 'one'
//          2, 3, 4    -> 'few'
//          5..20, 0   -> 'many'
// Never assume one == 1.

将复数与其他值结合

一个格式可以包含多个变量,例如计数和姓名。每个变量都可以独立进行复数化。在字符串目录中,您可以标记哪个插值会变化,其余部分会在所有变体中保持不变。

let files = 2
let folder = "Photos"
let text = String(
    localized: "\(files) files in \(folder)")
// 'files' drives the plural; 'folder' is substituted as-is
print(text)

宽度和设备变体

同一目录机制也支持设备和宽度变体,因此您可以在手表上显示较短的标签,在 iPad 上显示较长的标签,或在空间狭窄时使用缩写。这些变体可以与复数变体配合使用。

// Catalog can vary by:
//   plural: one / other
//   device: iPhone / iPad / watch
//   width:  short / medium / long
let label = String(localized: "Notifications")
print(label)

测试复数化

要验证变体,请使用 Xcode 的方案本地化覆盖,在每种目标语言中运行应用;或者使用伪语言和按 locale 划分的预览。请重点检查边界数字:0、1、2、5、11、21、100。

let samples = [0, 1, 2, 5, 11, 21, 100]
for n in samples {
    print(String(localized: "\(n) items"))
}

最佳实践

为了正确处理复数:

  • 不要拼接或硬编码 s 后缀。
  • 提供目标语言所需的每个类别。
  • 从插值整数驱动复数选择,而不是使用预先计算的字符串。
  • 新代码应优先使用字符串目录;仅为旧版目标保留 .stringsdict。
func cartSummary(_ items: Int) -> String {
    String(localized: "Your cart has \(items) items",
           comment: "Cart count; pluralized")
}
print(cartSummary(1))

快速检查

回顾应该如何处理复数选择。

回顾

您学会了符合 locale 规则的复数化:

  • Unicode 复数类别包括零、一、二、少量、多量、其他;每种语言使用其中的一个子集。
  • 字符串目录允许您为每个键添加复数变体;旧版 .stringsdict 通过 plist 实现相同功能。
  • 调用位置保持简单:插入计数,然后由框架选择变体。
  • 不要硬编码复数逻辑;一类别并不只是数字 1。

常见问题解答

「复数形式与 Stringsdict」课时是免费的吗?

是的 — 「复数形式与 Stringsdict」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。

「复数形式与 Stringsdict」这节课中我会学到什么?

处理不同语言的复数规则。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Swift Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「复数形式与 Stringsdict」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Swift Academy 课中编写并运行代码吗?

能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 字符串目录与本地化字符串
  2. 复数形式与 Stringsdict
  3. 区域设置感知的格式化
  4. 从右到左与布局方向
← 返回 Swift Academy