字符串字面量
详细了解字符串、here文档以及各种类型的符号。
字符串
Elixir 有两种字符串:单引号和双引号。它们在内部表示上存在显著差异,但也有很多共同点。例如:
- 字符串可以存储 UTF-8 编码的字符。
- 可以包含转义序列:
1`\a` BEL (0x07) `\e` ESC (0x1b) 2`\v` VT (0x0b) `\b` BS (0x08) 3`\f` FF (0x0c) `\s` SP (0x20) 4`\d` DEL (0x7f) `\n` NL (0x0a) 5`\t` TAB (0x09) `\r` CR (0x0d) 6`\xhh` 2 个十六进制数字 7`\uhhh` 1–6 个十六进制数字 - 支持使用
#{...}语法对 Elixir 表达式进行插值:1 iex> name = "dave" 2 "dave" 3 4 iex> "Hello, #{String.capitalize name}!" 5 "Hello, Dave!" - 可以使用反斜杠转义原本具有特殊含义的字符。
- 支持多行字符串(heredocs)。
多行字符串(Heredocs)
任何字符串都可以跨越多行。为了说明这一点,我们将同时使用 IO.puts 和 IO.write。我们使用 write 来输出多行字符串,因为 puts 总是自动添加换行符,而我们希望看到原始内容。来看下面的代码:
1IO.puts "start" 2IO.write " 3 my 4 string 5" 6IO.puts "end"
输出结果为:
1start 2 my 3 string 4end
注意,多行字符串保留了开头和结尾的换行符,以及中间行的前导空格。使用多行字符串符号可以解决这个问题。如果我们将字符串分隔符三重化(''' 或 """),并将结尾的分隔符缩进到与字符串内容相同的缩进位置,就可以得到如下效果:
1IO.puts "start" 2IO.write """ 3 my 4 string 5""" 6IO.puts "end"
上述代码的输出结果为:
1start 2my 3string 4end
多行字符串被广泛用于为函数和模块添加文档。
字面量符号(Sigils)
与 Ruby 类似,Elixir 为某些字面量提供了替代语法。我们之前已经见过正则表达式的例子,比如写成 ~r{...}。在 Elixir 中,这种以 ~- 开头的字面量被称为 字面量符号(sigils)。
一个字面量符号以波浪号开头,后跟一个大写或小写字母,接着是用某种分隔符包围的内容,可能还带有选项。分隔符可以是 <...>、{...}、[...]、( ...)、|...|、/.../、"..." 或 '...'。
字母决定了字面量符号的类型。以下是可用选项的列表:
~C用于不进行转义或插值的字符列表。~c用于进行转义和插值的字符列表,类似于单引号字符串。~D用于格式为yyyy-mm-dd的日期。~N用于格式为yyyy-mm-ddhh:mm:ss[.ddd]的原始时间(无时区信息)。~R用于不进行转义或插值的正则表达式。~r用于进行转义和插值的正则表达式。~S用于不进行转义或插值的字符串。~s用于进行转义和插值的字符串,类似于双引号字符串。~T用于格式为hh:mm:ss[.dddd]的时间。~W用于由空白字符分隔的单词列表,不进行转义或插值。~w用于由空白字符分隔的单词列表,进行转义和插值。
以下是一些使用不同分隔符的字面量符号示例:
1iex> ~C[1\n2#{1+2}] 2'1\\n2\#{1+2}' 3 4iex> ~c"1\n2#{1+2}" 5'1\n23' 6 7iex> ~S[1\n2#{1+2}] 8"1\\n2\#{1+2}" 9 10iex> ~s/1\n2#{1+2}/ 11"1\n23" 12 13iex> ~W[the c#{'a'}t sat on the mat] 14["the", "c\#{'a'}t", "sat", "on", "the", "mat"] 15 16iex> ~w[the c#{'a'}t sat on the mat] 17["the", "cat", "sat", "on", "the", "mat"] 18 19iex> ~D<1999-12-31> 20~D[1999-12-31] 21 22iex> ~T[12:34:56] 23~T[12:34:56] 24 25iex> ~N{1999-12-31 23:59:59} 26~N[1999-12-31 23:59:59]
~W 和 ~w 字面量符号可以接受可选的类型标识符 a、c 或 s,分别表示返回原子列表、字符列表或字符串列表。
分隔符可以是任意非单词字符。如果分隔符是 (、[、{ 或 <,则结束分隔符为对应的闭合符号。否则,结束分隔符是下一个未被转义的起始分隔符。
Elixir 不检查分隔符的嵌套结构,因此字面量 ~s{a{b} 的结果是一个三个字符的字符串 a{b。
如果起始分隔符是三个单引号或三个双引号,则该字面量被视为多行字符串(heredoc)。
1iex> ~w""" 2...> the 3...> cat 4...> sat 5...> """ 6["the", "cat", "sat"]
如果希望为多行字符串字面量指定修饰符,可以在结尾分隔符之后添加。
1iex> ~r""" 2...> hello 3...> """i 4~r/hello\n/i
字面量符号的一个有趣特性是:我们可以自定义自己的字面量符号。
请查看并运行以下代码: