我开始喜欢 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/