StringBuilder
s 的优势在于string
是由于最小化分配。它预先分配缓冲区以避免为每个插入/追加分配。这需要可变性——某个对象必须拥有(并改变)缓冲区。
Incidentally, System.String
already fits (what I can make of) your description: it's immutable and supports concatenation, insertionMSDN, and removalMSDN.
UPDATE
托马斯的想法引起了我的兴趣。采纳他的想法,这就是我的想法
type StringBuilder =
private
| Empty
| StringBuilder of int * string * int * StringBuilder
member this.Length =
match this with
| Empty -> 0
| StringBuilder(_, _, n, _) -> n
override this.ToString() =
let rec rev acc = function
| Empty -> acc
| StringBuilder(idx, str, _, bldr) -> rev ((idx, str)::acc) bldr
let buf = ResizeArray(this.Length)
for idx, str in rev [] this do buf.InsertRange(idx, str)
System.String(buf.ToArray())
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
[<RequireQualifiedAccess>]
module StringBuilder =
let empty = Empty
let length (bldr:StringBuilder) = bldr.Length
let insert index str bldr =
if index < 0 || index > (length bldr) then invalidArg "index" "out of range"
StringBuilder(index, str, str.Length + bldr.Length, bldr)
let create str = insert 0 str empty
let append str bldr = insert (length bldr) str bldr
let remove index count (bldr:StringBuilder) = create <| bldr.ToString().Remove(index, count)
Usage
let bldr =
StringBuilder.create "abcdef"
|> StringBuilder.insert 1 "xyz"
|> StringBuilder.append "123"
|> StringBuilder.remove 1 2
bldr.ToString() //azbcdef123
它是持久的并且插入是 O(1)。