【问题标题】:format String with array of Strings用字符串数组格式化字符串
【发布时间】:2016-07-21 17:32:01
【问题描述】:

我正在尝试创建一个带有 Strings 数组的 String,我希望这可以工作:

let format = "%@ and %@!"
let str1 = "bla"
let str2 = "blob"

private func formatItNicely(format: String, substrings: [String]) -> String {
    return String(format: format, arguments: substrings)
}

let result = formatItNicely(format, substrings: [str1, str2])

但我收到了fatal error: can't unsafeBitCast between types of different sizes

我已经看到thisthisthis 问题(以及更多),但我仍然不知道如何完成我想做的事情。

【问题讨论】:

  • “我希望这会起作用”我不明白你为什么会这样。数组不是可变参数。问题是 Swift 没有“splat”运算符。你不能一个数组变成一个可变参数。
  • @matt 我可以以某种不同的方式定义我的函数以便能够做到这一点吗?如果我将参数子字符串定义为 String... 我会得到相同的结果
  • 您可以手动将每个字符串按顺序替换为每个%@,而不使用String(format:)。否则,您将不得不对 C 可变参数的东西感到沮丧。

标签: ios arrays swift


【解决方案1】:

String(format:, arguments: ) 期望 [CVarArgType] 作为第二个 参数:

let format = "%@ and %@!"
let str1 = "bla"
let str2 = "blob"

private func formatItNicely(format: String, substrings: [CVarArgType]) -> String {
    return String(format: format, arguments: substrings)
}

let result = formatItNicely(format, substrings: [str1, str2])
print(result) // bla and blob!

但请注意,如果格式说明符不匹配,这可能会崩溃(或给出意外的输出) 实际参数,格式化函数不会(不能)检查。

【讨论】:

  • 当我打电话给String(format:,arguments:) 时,我最终做了substrings.map { $0 as CVarArgType }。这样子字符串不必是CVarArgType
【解决方案2】:

或者你可以使用可变参数:

private func formatItNicely(format: String, _ arguments: CVarArgType...) -> String {
    return String(format: format, arguments: arguments)
}

这样称呼它:

let format = "%@ and %@!"
let str1 = "bla"
let str2 = "blob"

let result = formatItNicely(format, str1, str2)

【讨论】:

    【解决方案3】:

    由于您没有做任何非常有趣的事情,因此您实际上不需要内置格式字符串逻辑。您可以自己进行替换:

    func join(_ arr : [String], withFormatString s: String) -> String {
        var s = s
        for str in arr {
            if let r = s.range(of: "%@") {
                s.replaceSubrange(r, with: str)
            }
        }
        return s
    }
    let result = join([str1,str2], withFormatString:format)
    

    【讨论】:

    • 吹毛求疵:如果arr 中的字符串包含%@,这可能会给出错误的结果:)
    • @MartinR 实际上我要指出的是,由于他不依赖于内置的字符串格式,他可以提供自己极不可能的替换标记。我喜欢连续使用五个倒置的感叹号。
    【解决方案4】:

    (现在)您不必执行上述建议的任何操作。

    Swift5 中,您可以将 Strings 数组作为 arguments 传递给 String.init(format:arguments:)

    因此,在没有任何类型转换/映射等的情况下,以下内容对我来说可以正常工作。

    let formatString = "First one: %1$@, second one: %2$@"
    label.text = String(format: formatString, arguments: ["hello", "blabla"])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多