結論
Xcode8(Swift3ぐらい?)からStringに文字列を繰り返すメソッドがあったのでこれが使える
let s = String(repeating: "ab", count: 10)
print(s)
// Prints "abababababababababab"
Appleのリファレンス Documentation > Swift > String > init(repeating:count:)
https://developer.apple.com/documentation/swift/string/2427723-init
はじめに
文字列を規定以上に増やしてエラーになるような処理のテストコードを書きたかった。
rubyだと次のように書ける。
"a" * 2 # => "aa"
そのため、Swift 4.1でも同じようなことをやろうと、何も考えずにオペレータオーバーライドでのそれっぽい考えとして次のようなのがあると思う
import Foundation
func * (left: String, right: Int) -> String {
var total = ""
(0..<right).forEach { _ in
total += left
}
return total
}
print("a" * 2) // => "aa"
print(("a" * 2).count) // => 2
しかし、これだとStringオブジェクトをループごとに+=
で作成してしまっていて無駄な気がする(例えば* 2000
にすると2,000のStringが作られてる気がする)。テストで使いたい、無駄なコピーしてでも手に入れたいわけだけど、なんだか気になる。
ここで、Appleのリファレンスを調べているとString(repeating: "ab", count: 10)
があることがわかった。
Swiftのコードは設計図共有サイトにあるので見てみる。まず、swift4.1のブランチ
public init(repeating repeatedValue: String, count: Int) {
if count == 0 {
self = ""
return
}
precondition(count > 0, "Negative count not allowed")
let s = repeatedValue
self = String(_storage: _StringBuffer(
capacity: s._core.count * count,
initialSize: 0,
elementWidth: s._core.elementWidth))
for _ in 0..<count {
self += s
}
なるほどねー、たしかにcountが0のときとかマイナスのときの処理は必要だよねーと思ったものの、最後に結局+=
で文字列を生成している様子。
ただ、swiftの最新2018-06-06のtag(swift-DEVELOPMENT-SNAPSHOT-2018-06-05-a)に切り替えてみると、ループで文字列を結合しているわけではないみたい🤔