Оператор (^)
объединяет две строки, например,
# "hello" ^ ", " ^ "world!";;
- : string = "hello, world!"
Если у вас есть список строк, вы можете использовать функцию String.concat
, которая принимает разделитель, и списокстроит и производит там конкатенацию эффективным способом:
# String.concat ", " ["hello"; "world"];;
- : string = "hello, world"
Почему использование оператора (^)
в цикле - плохая идея?Каждая конкатенация создает новую строку, а затем копирует содержимое обеих строк в новую строку.Таким образом, добавление N
строк приведет к приблизительно n^2
копированию (где n
- длина строки).То же самое верно для Java и других языков / библиотек, где конкатенация возвращает новую строку вместо изменения одного из ее аргументов.Обычное решение - использовать шаблон StringBuilder , который в OCaml представлен модулем Buffer .Предположим, у вас нет функции String.concat
, и вы хотели бы создать свою собственную эффективную функцию конкатенации (это также может быть полезно, поскольку Buffer
является более общим решением, чем String.concat
, и будет работать, когдаНапример, вы вводите не список).Вот наша реализация,
let concat xs =
let buf = Buffer.create 16 in
List.iter (Buffer.add_string buf) xs;
Buffer.contents buf
Эта функция создаст буфер, который автоматически изменит свой размер.16
- это только начальное предположение и может быть любым числом.Во второй строке мы просто перебираем все строки и помещаем их в буфер, и, наконец, просим буфер сформировать полученную строку.Вот как мы используем эту функцию:
# concat ["hello"; ", "; "world"];;
- : string = "hello, world"