在专门处理非可选String
值时,字符串插值和字符串连接之间可能有什么区别?
struct MyModel {
let value1: String
let value2: String
var displayNameByConcatenation: String {
return value1 + "-" + value2
}
var displayNameByInterpolation: String {
return "\(value1)-\(value2)"
}
}
displayNameByConcatenation
和displayNameByInterpolation
不同的情况?喜欢长的unicode字符串吗?+
的行为或插值行为以使它们在上述示例中有所不同?请注意,从this question我们了解到字符串插值将使用CustomStringConvertible的description
。但String
连接(运算符+
)是否也会调用description
?
答案 0 :(得分:3)
从速度的角度来看,为了区分连接(value1 + "-" + value2
)和插值("\(value1)-\(value2)"
),结果可能取决于为获得最终字符串而完成的操作数。
我在iPhone 8上的搜索结果显示:
感谢警笛发现一个并不总是比另一个更快!
自己尝试(并且不要忘记根据需要调整经过测试的字符集和迭代):
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
}
}
答案 1 :(得分:0)
字符串插值:
一个缺点:
插值和连接都有自己的优点和缺点
需要使用与预定义字符串的串联来获得更好的性能
答案 2 :(得分:0)
“连接允许您将字符串组合在一起,它只适用于两个字符串。”
更新。不确定Swift的早期版本是什么允许的,但是目前你可以在同一个语句中连接两个以上的字符串:
让str =“嗨,我的名字是”
var concat = str +“2”+“3”+“4”+“5”+“works”//显示“嗨,我的名字是2345作品”
因为+的两个操作数都需要是字符串,如果你想在字符串中添加一个数字,你必须做一些额外的工作:
var concat2 = str + String(2)//显示“嗨,我的名字是2”
插值而不是连接的原因,这里是Apple插值介绍的引用:“字符串插值是一种从常量,变量,文字和表达式的混合构造新String值的方法”换句话说,你可以使用插值与数字,布尔值等,而不先将它们变成字符串,如果使用串联则必须这样做。