在Swift中,如何将格式化的Int值插入到字符串中?

12

这似乎是一个非常基本的问题,但我似乎无法在任何地方找到答案:( 我能够在Objective C中做到这一点,但我在Swift中卡住了。

我需要做的:

  1. 获取整数值
  2. 将其格式化为本地化字符串
  3. 使用stringWithFormat等效方法将该值注入到另一个字符串中(由于另一个字符串也被本地化,因此在下面的简化示例中未显示)

Objective C中如何轻松完成-这很有效:

    // points is of type NSNumber *

    NSNumberFormatter *formatter = [NSNumberFormatter new];
    formatter.locale             = [NSLocale currentLocale];
    formatter.numberStyle        = NSNumberFormatterDecimalStyle;

    NSString *ptsString = [formatter stringFromNumber:points];
    NSString *message   = [NSString stringWithFormat:@"You've earned %@ points", ptsString];

我在 Swift 中尝试实现这个最佳方案,但是最后一行出现编译错误:

    // points is of type Int

    let formatter         = NSNumberFormatter()
    formatter.locale      = NSLocale.currentLocale()
    formatter.numberStyle = NSNumberFormatterStyle.DecimalStyle

    let ptsString = formatter.stringFromNumber(points)!
    let message   = String(format: "You've earned %@ points", arguments: ptsString)

在Xcode中,我在最后一行代码遇到了以下错误:

"Cannot convert value of type 'String' to expected argument type '[CVarArgType]'"

(在我的实际代码中,我想要插入点值的消息本身也是本地化的,但是我简化了这个例子,因为在两种情况下都出现了完全相同的错误。)

我错过了什么..?

非常感谢任何帮助,

Erik


这确实是非常基础的。请阅读Swift语言指南中的字符串和字符章节,其中包括字符串插值的段落。 - vadian
谢谢。正在阅读中... - Erik van der Neut
啊,是的,我知道这个。我应该在我的问题中澄清一下,因为带有“%@”的消息实际上是本地化的,翻译成了8种不同的语言,所以我不能使用字符串插值。 - Erik van der Neut
2
你差不多就快成功了。在这行代码 let message = String(format: "You've earned %@ points", arguments: ptsString) 中,只需要删除 arguments: 即可... 也就是说,它应该是 let message = String(format: "You've earned %@ points", ptsString) - 0x416e746f6e
啊,谢谢Anton!我现在明白了...如果我把它拿掉,确实可以工作。如果我把它留下来,那么我需要将变量包装在一个集合中(正如totiG所指出的)。 - Erik van der Neut
1
只是为了澄清 - 如果您使用带有参数的字符串格式化初始化程序,则需要将其包装在数组中。如果省略参数,则不需要将其包装在数组中。原因是参数有两个初始化程序 - 一个接受CVarArgType数组,另一个接受可变参数。通过指定参数,您正在尝试使用需要数组的初始化程序。 - totiDev
2个回答

23
你需要将参数放入一个集合中。就像这样:
let message   = String(format: "You've earned %@ points", arguments: [ptsString])

你还可以使用这种方法:
let message   = "You've earned \(ptsString) points"

此外,您可以创建一个扩展方法来完成这个任务。
extension String {
    func format(_ parameters: CVarArg...) -> String {
        return String(format: self, arguments: parameters)
    }
}

现在你可以这样做:
let message = "You've earned %@ points".format("test")
let message2params = "You've earned %@ points %@".format("test1", "test2")

啊,谢谢!将其包装在集合中确实解决了问题:String(format: "You've earned %@ points", arguments: [ptsString])。为什么在这种情况下需要这样做呢?从我在网上看到的其他示例中,我没有看到关于参数变量的 [] 括号... - Erik van der Neut
1
你不需要将参数包装成数组,可以参考安东的评论来解决问题。 - Martin R
太棒了!感谢大家的超快速响应。哇...非常感谢! - Erik van der Neut

21
有时候,您需要更多的控制——所以如果您需要有前导零,您可以像在Objective-C中一样使用 'stringWithFormat'。

有时候需要更精确地控制输出,比如要求数字前面有 0。这时候可以像在 Objective-C 中一样使用 'stringWithFormat' 方法。

let ptsString = String(format: "%02d", points)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接