我一直在思考swift的字符串格式化的可能实现,其中大多数归结为“使用NSString(格式:...)”这一切都很好,但我想要一个简洁易读的格式,所以我决定实现类似python的%格式化运算符:
@infix func % (value:Double, format:String) -> String {
return NSString(format:format, value)
}
这适用于Double's,因为我可以使用:
println("PI = " + M_PI % "%.3f")
导致:
PI = 3.142
虽然我可以创造其中的5个,但我想把它变成一个通用函数:
@infix func %<T> (value:T, format:String) -> String {
return NSString(format:format, value)
}
但这导致了消息:
Could not find an overload for 'init' that accepts the supplied arguments
合理的,我可以传入一个元组,或者同样非客观的东西-C。 (注意,为了真正做到这种Python风格,我希望传入一个元组,但这是另一个问题,超出了这个问题的范围)
我尝试声明我自己的空协议并在Double上实现它,但它根本没有帮助。
protocol NSStringFormattable {}
extension Double : NSStringFormattable {}
@infix func % <T:NSStringFormattable> (value:T, format:String) -> String {
return NSString(format:format, value)
}
我显然可以做一些事情,例如为每个类添加一个格式函数,然后根据格式函数定义运算符,但在许多方面,这并不比定义5个不同的运算符重载更好。
protocol NSStringFormattable {
func format(format:String) -> String
}
extension Double : NSStringFormattable {
func format(format:String) -> String {
return NSString(format:format, self)
}
}
@infix func % <T:NSStringFormattable> (value:T, format:String) -> String {
return value.format(format)
}
如何将T限制为只能传递给NSString(format:...)
的那些类型?
答案 0 :(得分:2)
发现它!
@infix func % (value:CVarArg, format:String) -> String {
return NSString(format:format, value)
}
这个单一功能允许:
5 % "%04x"
3.4 % "%.3f"
M_PI % "%.3f"
Int64(32) % "%04X"
不幸的是,它还允许:
"String" % "%3.3s"
并生成垃圾,但欢迎使用printf而不进行参数类型检查
更进一步,通过定义一组函数:
@infix func % (values:(CVarArg, CVarArg), format:String) -> String {
return NSString(format:format, values.0, values.1)
}
@infix func % (values:(CVarArg, CVarArg, CVarArg), format:String) -> String {
return NSString(format:format, values.0, values.1, values.2)
}
我们可以实现类似python的影响:
(M_PI, 5) % "%.3f->%d"
每个元组长度必须定义一个丑陋,但我会继续攻击它:)
答案 1 :(得分:0)
据我所知(与你经历了相同的旅程),泛型不是这里的解决方案,而是多次重载(这不是很漂亮) -
operator infix % { }
@infix func % (format: String, value: Double) -> String {
return NSString(format:format, value)
}
@infix func % (format: String, value: Float) -> String {
return NSString(format:format, value)
}
@infix func % (format: String, value: Int) -> String {
return NSString(format:format, value)
}
抱歉,从您的示例中反转参数顺序 - 允许
println("PI = %.3f" % M_PI)