string - 是否有等效于使用 Swift 格式的字符串函数 String(format : . ..)

标签 string swift

我开始喜欢 Swift 字符串格式,因为它在字符串中使用变量名,而不是像“%@”这样模棱两可的格式标签

我想从一个包含 Swift 样式格式的文件中加载一个大字符串(像这样)

Now is the time for all good \(who) to come to babble incoherently.

然后我想将该 String 变量的内容提供给一个语句,以免我替换

\(who)

运行时常量/变量 who 的内容。

下面的代码使用一个字符串常量作为格式化字符串。

let who = "programmers"
let aString = "Now is the time for all good \(who) to come to babble incoherently."

该代码对出现在我的代码中的带引号的字符串进行格式化。

相反,我想要类似代码的东西

let formatString = "Now is the time for all good %@ to come to babble incoherently."
aString = String(format: formatString, who)

但是我可以在从文件中读取的常量/变量中传入 Swift 样式的格式字符串。

这可能吗?我没有找到它,因为我不确定要使用什么搜索词。

如果必须的话,我总是可以使用 C 风格的字符串格式化和 String 类的 initWithFormat 方法......

最佳答案

我认为没有办法做到这一点。字符串插值是通过符合 StringInterpolationConvertible 协议(protocol)来实现的,并且您可能希望以与 StringLiteralConvertible 所需方法相同的方式利用它,一个啦:

let someString = toString(42)

// this is the method String implements to conform to StringLiteralConvertible
let anotherString = String(stringLiteral: someString)

// anotherString will be "42"
print(anotherString)

不幸的是,您不能使用 StringInterpolationConvertible 来完成相同的技巧。查看协议(protocol)的工作原理可能会有所帮助:

struct MyString: Printable {
    let actualString: String
    var description: String { return actualString }
}

extension MyString: StringInterpolationConvertible {
    // first, this will get called for each "segment"
    init<T>(stringInterpolationSegment expr: T) {
        println("Processing segment: " + toString(expr))
        actualString = toString(expr)
    }
    // here is a type-specific override for Int, that coverts
    // small numbers into words:
    init(stringInterpolationSegment expr: Int) {
        if (0..<4).contains(expr) {
            println("Embigening \(expr)")
            let numbers = ["zeo","one","two","three"]
            actualString = numbers[expr]
        }
        else {
            println("Processing segment: " + toString(expr))
            actualString = toString(expr)
        }
    }
    // finally, this gets called with an array of all of the
    // converted segments
    init(stringInterpolation strings: MyString...) {
        // strings will be a bunch of MyString objects
        actualString = "".join(strings.map { $0.actualString })
    }
}

let number = 3
let aString: MyString = "Then shalt thou count to \(number), no more, no less."
println(aString)
// prints "Then shalt thou count to three, no more, no less."

因此,虽然您可以根据需要直接调用 String.init(stringInterpolation:)String.init(stringInterpolationSegment:)(只需尝试 String (stringInterpolationSegment: 3.141)String(stringInterpolation: "blah", "blah")),这对你帮助不大。您真正需要的是一个外观函数来协调对它们的调用。除非标准库中有一个方便的预先存在的函数来完成我错过的事情,否则我认为你运气不好。我怀疑它是编译器内置的。

您也许可以编写自己的代码来实现您的目标,但需要付出很多努力,因为您必须将要手动插入的字符串分解为位并自己处理,调用段 init 在一个循环中。此外,您在调用组合函数时也会遇到问题,因为您无法将数组拼成可变参数函数调用。

关于string - 是否有等效于使用 Swift 格式的字符串函数 String(format : . ..),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29749187/

相关文章:

c# - 从 XmlReader 的字符串中删除\"转义字符

C:生成缓冲区

ios - View 变换旋转使 iOS 中的图像渲染效果无效

ios - Swift - 从 UITableView 中删除单元格

ios - 从 UIButton 调用 prepareforSegue?

java - 为什么我收到字符串索引超出范围 : 97?

android - 为什么我在 xml 中写的文本不显示?

java - 字符串池对象

ios - Safari View Controller URL/导航框(文本字段)颜色

ios - 在 iOS10+ 播放完成后,如何从锁屏中消失播放器控件?