如何将字符串附加到OCaml中的字符串?

Sof*_*mur 9 string ocaml char

似乎在类型的标准库中没有函数char -> string -> string,它在a char的前面(或者在a的末尾插入)string.有解决方法,例如使用String.makeString.blit.有一种优雅的方式来做到这一点?

Jef*_*eld 18

来自@pad的代码就是我要使用的代码,因为我喜欢将字符串视为不可变的.但我不会用Char.escaped; 它专门用于你想要角色的OCaml词汇表示.所以,如果你做出改变,这就是你得到的:

let prefix_char s c = String.make 1 c ^ s

let suffix_char s c = s ^ String.make 1 c
Run Code Online (Sandbox Code Playgroud)

更新

自从提出这个问题以来的几年里,OCaml已经改变,因此字符串是不可变的.优秀.


pad*_*pad 8

String.makeString.blit是一个很好的方法,但它们似乎是必要的.我个人更喜欢使用Char.escaped和字符串连接来创建中缀函数:

let (^$) c s = s ^ Char.escaped c (* append *)
let ($^) c s = Char.escaped c ^ s (* prepend *)
Run Code Online (Sandbox Code Playgroud)

  • 我会说`Char.escaped`是专门用于生成OCaml代码作为输出或编写人类可读消息的用途.对于普通情况,`String.make 1 c`可能就是你想要的.它确实看起来有点笨拙.电池有'BatString.of_char`. (8认同)
  • 为什么在@ JeffreyScofield的答案和评论中清楚地表达了一切? (2认同)

Rok*_*iša 8

我对不同方法的效率进行了比较:

  1. 我写了一个简单的测试:

    let append_escaped s c = s ^ Char.escaped c
    let append_make    s c = s ^ String.make 1 c
    let append_sprintf s c = Printf.sprintf "%s%c" s c
    
    let _ =
      let s = "some text" in
      let c = 'a' in
      for i = 1 to 100000000 do
        let _ = append_(*escaped|make|sprintf*) s c in ()
      done
    
    Run Code Online (Sandbox Code Playgroud)
  2. 我原生编译(Intel Core 2 Duo).

  3. 我为每个选项运行了三次测试,计时time并计算平均实时时间.

结果如下:

  1. s ^ String.make 1 c:7.75秒(100%)

  2. s ^ Char.escaped c:8.30s(107%)

  3. Printf.sprintf "%s%c" s c:68.57s(885%)

  • 请注意:`Char.escaped`与`String.make`的作用不同.根据OCaml的词汇规则,它为角色创建了一个"逃逸"值.要看到这一点,请尝试以这种方式添加换行符("\n").这也是为什么它有点慢.对于大多数一般用途,您希望使用`String.make 1 c`.自然地,'Printf.sprintf`慢很多,但非常灵活. (2认同)