字符串插值和字符串连接之间的区别 [英] Difference between String interpolation and String concatenation
问题描述
当专门处理非可选的String
值时,字符串插值和字符串串联有什么区别?
When specifically dealing with non-optional String
values, what could be the difference between String interpolation and String concatenation?
struct MyModel {
let value1: String
let value2: String
var displayNameByConcatenation: String {
return value1 + "-" + value2
}
var displayNameByInterpolation: String {
return "\(value1)-\(value2)"
}
}
- 在任何情况下
displayNameByConcatenation
和displayNameByInterpolation
是不同的吗?像长长的unicode字符串一样? - 在上面的示例中,是否可以以某种方式覆盖运算符
+
的行为或插值行为以使其与众不同? - 一个比另一个快/慢吗?
- Is there going to be any case where
displayNameByConcatenation
anddisplayNameByInterpolation
are different? Like on long unicode strings? - Is it possible to somehow override the behavior of operator
+
or the behavior of interpolation to make them different in above example? - Is one faster/slower than the other?
- 如果大约< 30个子字符串连接在一起,则连接速度更快
- 如果大约有30个以上的子字符串要附加在一起,则插值会更快
请注意,通过此问题,我们可以了解到该字符串插值将使用CustomStringConvertible的description
.但是String
串联(运算符+
)是否也调用description
?
Note that from this question we learn that string interpolation will use the description
of a CustomStringConvertible. But does String
concatenation (operator +
) also calls the description
?
推荐答案
从速度的角度来看,要区分级联(value1 + "-" + value2
)和插值("\(value1)-\(value2)"
),结果可能取决于对获取最终的字符串.
From a speed point of view, to differentiate concatenation (value1 + "-" + value2
) and interpolation ("\(value1)-\(value2)"
), results may depend on the number of operations done to obtain the final string.
我在iPhone 8上的结果显示:
My results on an iPhone 8 show that:
谢谢塞伦斯(Sirens)弄清楚一个并不一定总是比另一个要快!
Thank you Sirens for figuring out that one wasn't always faster than the other!
亲自尝试一下(不要忘了根据您的需要调整经过测试的字符集和迭代):
Try it yourself (and don't forget to adapt the tested character set and iterations for your needs):
import UIKit
class ViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
DispatchQueue.global(qos: .default).async {
ViewController.buildDataAndTest()
}
}
private static func buildDataAndTest(times: Int = 1_000) {
let characterSet = CharacterSet.alphanumerics
characterSet.cacheAllCharacters()
let data: [(String, String)] = (0 ..< times).map { _ in
(characterSet.randomString(length: 50), characterSet.randomString(length: 20))
}
_ = testCIA(data)
_ = testInterpol(data)
print("concatenation: " + String(resultConcatenation))
print("interpolation: \(resultInterpolation)")
}
/// concatenation in array
static var resultConcatenation: CFTimeInterval = 0
private static func testCIA(_ array: [(String, String)]) -> String {
var foo = ""
let start = CACurrentMediaTime()
for (a, b) in array {
foo = foo + " " + a + "+" + b
}
resultConcatenation = CACurrentMediaTime() - start
return foo
}
/// interpolation
static var resultInterpolation: CFTimeInterval = 0
private static func testInterpol(_ array: [(String, String)]) -> String {
var foo = ""
let start = CACurrentMediaTime()
for (a, b) in array {
foo = "\(foo) \(a)+\(b)"
}
resultInterpolation = CACurrentMediaTime() - start
return foo
}
}
extension CharacterSet {
static var cachedCharacters: [Character] = []
public func cacheAllCharacters() {
CharacterSet.cachedCharacters = characters()
}
/// extracting characters
/// https://stackoverflow.com/a/52133647/1033581
public func characters() -> [Character] {
return codePoints().compactMap { UnicodeScalar($0) }.map { Character($0) }
}
public func codePoints() -> [Int] {
var result: [Int] = []
var plane = 0
for (i, w) in bitmapRepresentation.enumerated() {
let k = i % 8193
if k == 8192 {
plane = Int(w) << 13
continue
}
let base = (plane + k) << 3
for j in 0 ..< 8 where w & 1 << j != 0 {
result.append(base + j)
}
}
return result
}
// http://stackoverflow.com/a/42895178/1033581
public func randomString(length: Int) -> String {
let charArray = CharacterSet.cachedCharacters
let charArrayCount = UInt32(charArray.count)
var randomString = ""
for _ in 0 ..< length {
randomString += String(charArray[Int(arc4random_uniform(charArrayCount))])
}
return randomString
}
}
这篇关于字符串插值和字符串连接之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!