标准库中似乎没有类型为char -> string -> string
的函数,可以将一个char
插入到string
的前面(或末尾)。有一些解决方法,比如使用String.make
或String.blit
。是否有更优雅的方法来实现这个功能?
@pad的代码是我会使用的,因为如果可能的话,我喜欢将字符串视为不可变的。但我不会使用Char.escaped
;它是专门用于当您想要字符的OCaml词法表示时。因此,如果进行更改,您将获得以下结果:
let prefix_char s c = String.make 1 c ^ s
let suffix_char s c = s ^ String.make 1 c
更新
自从这个问题被提出以来的这些年里,OCaml已经发生了变化,使得字符串是不可变的。非常好。
String.make
和String.blit
是一种不错的方法,但它们似乎是命令式的。个人更喜欢使用Char.escaped
和字符串连接来创建中缀函数:
let (^$) c s = s ^ Char.escaped c (* append *)
let ($^) c s = Char.escaped c ^ s (* prepend *)
Char.escaped
适用于生成OCaml代码输出或编写可读性强的消息等专业用途。对于普通情况,String.make 1 c
可能是您想要的。它似乎有点笨拙。Batteries库中有BatString.of_char
。 - Jeffrey ScofieldChar.escaped
的澄清。我将保持答案不变,以便其他人了解它。 - padI wrote a simple test:
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
I compiled it natively (Intel Core 2 Duo).
I ran the test three times for each option, timing it with time
, and calculating the mean real time elapsed.
s ^ String.make 1 c
:7.75秒(100%)
s ^ Char.escaped c
:8.30秒(107%)
Printf.sprintf "%s%c" s c
:68.57秒(885%)
Char.escaped
和String.make
的功能不同。它根据OCaml的词法规则为字符创建一个“转义”值。如果要尝试通过这种方式添加换行符('\n'
),就会看到这一点。这也是为什么它稍微慢一些的原因。对于大多数一般用途,您应该使用String.make 1 c
。当然,Printf.sprintf
速度要慢得多,但非常灵活。 - Jeffrey ScofieldChar.escaped '\n'
= "\\n"
。 - Rok StrnišaChar.escaped '\n'
会给你一个由'\\'
和'n'
组成的两个字符的字符串。String.make 1 '\n'
会给你一个由'\n'
组成的一个字符的字符串,这更可能是你想要的。 - Jeffrey Scofield
Buffer
对于增长字符串可能更加合适。 - Basile Starynkevitch