我开始喜欢Swift字符串格式,因为它在字符串中使用变量名,而不是像“%@”那样含糊不清的格式标签
我想从一个包含Swift风格格式的文件中加载一个大字符串(就像这样)
Now is the time for all good \(who) to come to babble incoherently.
然后我想将该String变量的内容提供给一个语句,以免我替换
\(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)
这可能吗?我没有任何运气搜索它,因为我不确定要使用哪些搜索条件。
如果必须的话,我总是可以使用C风格的字符串格式和String类的initWithFormat方法...
答案 0 :(得分:3)
我认为没有办法做到这一点。字符串插值是通过符合StringInterpolationConvertible
协议来实现的,并且可能您希望以与StringLiteralConvertible
所需的方法相同的方式进入字符串,la:
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
做同样的伎俩。了解协议的工作原理可能会有所帮助:
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")
),这对您没有多大帮助。你真正需要的是一个Facade函数,它协调对它们的调用。除非在标准库中有一个方便的预先存在的函数,它完全符合我错过的功能,否则我认为你运气不好。我怀疑它是内置于编译器中的。
您可以编写自己的目标,但需要付出很多努力,因为您必须将要手动插入的字符串拆分为位并自行处理,调用段init
一个循环。此外,您将遇到调用组合函数的问题,因为您无法将数组splat到可变参数函数调用中。
答案 1 :(得分:1)
我不这么认为。编译器需要能够在编译时解析插值变量。
答案 2 :(得分:0)
我不是Swift程序员,具体而言,但我认为你可以使用Dictionary和标准的字符串替换和拆分方法将它解决为你想要的东西:
var replacement = [String: String]()
replacement["who"] = "programmers"
有了这个,你可以尝试找到“\(”,“读取下一个”和“之前的内容”的出现次数,(this post可以帮助拆分部分,this one,替换部分),在字典中找到它,并从你得到的部分重建你的字符串。
答案 3 :(得分:-2)
这个就像一个魅力:
let who = "programmers"
let formatString = "Now is the time for all good %@ to come to babble incoherently."
let aString = String(format: formatString, who)