Ответ 1
StaticString
можно узнать во время компиляции. Это может привести к оптимизации. Пример:
EDIT: эта часть не работает, см. ниже приведенное ниже
Предположим, что у вас есть функция, которая вычисляет Int
для некоторых значений String
для некоторых констант, которые вы определяете во время компиляции.
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
познаваемый во время компиляции, так что угадайте, что он делает? Он запускает функцию прямо во время компиляции (насколько это удивительно!). Однажды я прочитал статью об этом, автор проверил сгенерированную сборку и фактически нашел уже вычисленные числа.
Как вы можете видеть, это может быть полезно в некоторых случаях, например, упомянутом выше, чтобы не уменьшать производительность во время выполнения для вещей, которые можно выполнить во время компиляции.
EDIT: Dániel Nagy и я имел беседу. Вышеприведенный пример не работает, потому что функция stringValue
StaticString
не может быть известна во время компиляции (потому что она возвращает a String
). Вот лучший пример:
func countStatic(string: StaticString) -> Int {
return string.byteSize // Breakpoint here
}
func count(string: String) -> Int {
return string.characters.count // Breakpoint here
}
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 // Breakpoint here
}
срабатывают обе точки останова.
По-видимому, есть некоторые методы, которые можно выполнить во время компиляции, а другие - нет. Интересно, как на самом деле это компилятор.