Swift 格式说明符的 NSLocalizedString 产生垃圾

NSLocalizedString with format specifiers in Swift yields garbage

为了在我的一个非常小的应用程序中更容易本地化,我有这个字符串扩展方法:

extension String {
    func localized(with values: Any...) -> String {
        // debug values
        for v in values {
            print("\(type(of: v)): \(v)")
        }

        return String.localizedStringWithFormat(NSLocalizedString(self, comment: ""), values)
    }
}

我的 Localizable.strings 德文本地化版本包含此 key/value 对: "WeeksFuture" = "In %d Wochen";

这样做:

for _ in 0..<5 {
    let localized = "WeeksFuture".localized(with: 3)
    print(localized)
}

同时将 Xcode 设置为用德语调试应用程序(尽管这也发生在所有其他语言中)将其打印到输出 window:

Int: 3
In 151.456 Wochen
Int: 3
In 186.912 Wochen
Int: 3
In 186.880 Wochen
Int: 3
In 187.264 Wochen
Int: 3
In 187.488 Wochen

显然,这都是错误的。为什么我先得到的是"Int: 3"的正确输出,然后是一个看似随机的垃圾数字的字符串?

String.localizedStringWithFormat 接受 StringCVarArg... 作为参数。您传入了一个 Any - values 的数组作为第二个参数。它强制将数组转换为十进制数,导致奇怪的结果。

要解决这个问题,您只需要找到一个采用 [CVarArg] 的重载即可。幸运的是,有一个像这样的 init 重载:

 return String.init(format: 
    NSLocalizedString(self, comment: ""), arguments: values)

但是,values 是一个 [Any],与预期的 [CVarArg] 不兼容。您可能应该更改参数类型。

所以你的整个扩展看起来像这样:

func localized(with values: CVarArg...) -> String {
    return String.init(format: NSLocalizedString(self, comment: ""), arguments: values)
}