StaticString
在编译时是可知的。这可以导致优化。例如:
编辑:此部分不起作用,请参见下面的编辑
假设您有一个函数,它为一些在编译时定义的常量的一些String
值计算一个Int
。
let someString = "Test"
let otherString = "Hello there"
func numberForString(string: String) -> Int {
return string.stringValue.unicodeScalars.reduce(0) { $0 * 1 << 8 + Int($1.value) }
}
let some = numberForString(someString)
let other = numberForString(otherString)
像这样,当程序执行时(例如在应用程序启动时),函数将使用“Test”和“Hello there”被调用并运行。这绝对是在运行时发生的。但是,如果您更改函数以使用StaticString
参数,则...
func numberForString(string: StaticString) -> Int {
return string.stringValue.unicodeScalars.reduce(0) { $0 * 1 << 8 + Int($1.value) }
}
编译器意识到传入的
StaticString
在编译时可知,所以你猜它会做什么?它直接在编译时运行该函数(多么棒啊!)。我曾经读过一篇文章,作者检查了生成的汇编代码,实际上他发现已经计算出了数字。
正如你所看到的,这在某些情况下非常有用,比如上述例子中可以节省运行时间,因为这些任务可以在编译时完成。
编辑:
Dániel Nagy和我
进行了交谈。我之前给出的例子不起作用,因为
StaticString
的
stringValue
函数无法在编译时确定(因为它返回一个
String
)。这里是一个更好的例子:
func countStatic(string: StaticString) -> Int {
return string.byteSize
}
func count(string: String) -> Int {
return string.characters.count
}
let staticString : StaticString = "static string"
let string : String = "string"
print(countStatic(staticString))
print(count(string))
在发布版本中,只有第二个断点会被触发,如果你将第一个函数更改为
func countStatic(string: StaticString) -> Int {
return string.stringValue.characters.count
}
两个断点都被触发。
显然,有些方法可以在编译时完成,而其他方法则不能。我想知道编译器如何实际确定这一点。
StaticString
不能被改变,但也可以被重新分配。因此,基本上编译器无法确定其值。 - Dániel NagyStaticString
的变量将保存哪个值,但是它确信分配给该变量的任何值都是在编译时已知的字符串文字。Swift将如何处理这些信息只有Swift作者在发布开源代码之前才知道。 - vacawama