<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>String on cnDenis的笔记</title><link>https://blog.cndenis.com/tags/String.html</link><description>Recent content in String on cnDenis的笔记</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Thu, 12 Sep 2013 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.cndenis.com/tags/String/index.xml" rel="self" type="application/rss+xml"/><item><title>Erlang中的原子、字符串和二进制串</title><link>https://blog.cndenis.com/Erlang/2013/04/Erlang%E4%B8%AD%E7%9A%84%E5%8E%9F%E5%AD%90%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%92%8C%E4%BA%8C%E8%BF%9B%E5%88%B6%E4%B8%B2.html</link><pubDate>Fri, 26 Apr 2013 00:00:00 +0000</pubDate><guid>https://blog.cndenis.com/Erlang/2013/04/Erlang%E4%B8%AD%E7%9A%84%E5%8E%9F%E5%AD%90%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%92%8C%E4%BA%8C%E8%BF%9B%E5%88%B6%E4%B8%B2.html</guid><description>&lt;p&gt;Erlang中的原子（Atom）, 字符串（String）和二进制串（Binary）是有点容易让人糊涂
的东西, 这里归纳一下它们之间的区别与联系。&lt;/p&gt;
&lt;h2 id="原子"&gt;原子
&lt;/h2&gt;&lt;p&gt;原子是由小写字母开头, 后接大小写字母及数字及下划线的, 比方说abc, cDE, ff89,
或是由单引号&amp;rsquo;&amp;lsquo;括起来的任意字符, 比方说&amp;rsquo;EXIT&amp;rsquo;, &amp;lsquo;!@#@!$sdaf&amp;rsquo;。
用过其他语言的话, 会觉得Erlang中没括起来的原子长得像变量, 括起来的
长得像字符串, 但其实都不是, 这点要特别注意。Erlang中的变量是以大写字母
开头的, 字符串是用双引号括起来的。&lt;/p&gt;
&lt;p&gt;原子在Erlang中应用非常广, 模块名、函数名、记录名都是原子, 所以如果你够蛋疼的话,
可以用&amp;rsquo;!#@$#y3fdsa1&amp;rsquo;（包括两边的单引号）当做函数名。&lt;/p&gt;
&lt;p&gt;原子顾名思义是“不可分割”的东西, 原子无论长短, 在内存中占用的空间都是一样的,
然而, 原子的名字也不是毫无意义的, 可以利用&lt;code&gt;atom_to_binary&lt;/code&gt;把原子名转成二进制串,
也可以用&lt;code&gt;atom_to_list&lt;/code&gt;把原子名转成字符串。
反过来也可以, 有&lt;code&gt;binary_to_atom&lt;/code&gt;和&lt;code&gt;list_to_atom&lt;/code&gt;可以用。&lt;/p&gt;
&lt;p&gt;Erlang中是没有原生的原子连接方法, 真想要相连的话, 先要转成二进制串或是字符串.&lt;/p&gt;
&lt;h2 id="字符串"&gt;字符串
&lt;/h2&gt;&lt;p&gt;Erlang中字符串是使用双引号括起来的一串字符, 例如&amp;quot;string&amp;quot;, &amp;ldquo;123&amp;quot;等等。
双引号其实只是一个简写形式, 其实并没有把“字符串”当作一种独立的数据类型,
而是用正整数的列表（List）作为字符串使用, 跟C里面的做法相似。以下三行是等价的：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-erlang" data-lang="erlang"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;hello&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sc"&gt;$h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;$l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;$l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;$o&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;104&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;108&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;108&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;111&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;因此字符串转换成原子及二进制串的的函数名为&lt;code&gt;list_to_atom&lt;/code&gt;和&lt;code&gt;list_to_binary&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;Erlang中的有专门处理字符串的模块, &lt;code&gt;string&lt;/code&gt;, 可以用以进行大小写变换、截断、
对齐、连接、分割、子字符串等等常用操作。由于字符串实质上是列表, 因此&lt;code&gt;lists&lt;/code&gt;
模块里的方法也全都适用于字符串。&lt;/p&gt;
&lt;p&gt;字符串是列表, 因此可以使用列表的连接运算符&lt;code&gt;++&lt;/code&gt;进行连接。二进制串是不可以用&lt;code&gt;++&lt;/code&gt;的。
虽然拿 &lt;code&gt;字符串++二进制串&lt;/code&gt; 在语法上是允许的, 但得到的结果是一个 &amp;ldquo;非正规列表&amp;rdquo;
（也有人翻译成 &amp;ldquo;非严格列表&amp;rdquo; ）, 是不推荐这么做的。&lt;/p&gt;
&lt;h2 id="二进制串"&gt;二进制串
&lt;/h2&gt;&lt;p&gt;二进制串是Erlang的一项特色, 使用在代码中使用&lt;code&gt;&amp;lt;&amp;lt; &amp;gt;&amp;gt;&lt;/code&gt;括起来（看起来有点像中文的
书名号, 其实是两个小于号和两个大于号）。括起来的内容可以用数字表示, 或是用对应
的字符串表示, 如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-erlang" data-lang="erlang"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;97&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;98&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;abc&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这两者含义是相同的。但要注意的是, 和列表&lt;code&gt;[ ]&lt;/code&gt;或元组&lt;code&gt;{ }&lt;/code&gt;不一样的是,
双引号只是一种简记方式, 并不是说把一个字符串放到&lt;code&gt;&amp;lt;&amp;lt; &amp;gt;&amp;gt;&lt;/code&gt;里就会变成二进制串的,
比方说以下的写法都是不对的。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-erlang" data-lang="erlang"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;97&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;98&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;A&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;abc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nv"&gt;A&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;正确的做法是:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-erlang" data-lang="erlang"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;A&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;abc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;A1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;list_to_binary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nv"&gt;A1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;binary&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c"&gt;%% 或者
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;list_to_binary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;binary&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;记住, &lt;strong&gt;在二进制串中使用函数的话, 必须要用括号括起来&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;&amp;lt; &amp;gt;&amp;gt;&lt;/code&gt;里可以接受数字和二进制串, 利用所谓的比特语法构造二进制串或进行模式匹配。
格式为 &lt;code&gt;变量:大小/类型&lt;/code&gt;, 例如:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-erlang" data-lang="erlang"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;X&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;little&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;signed&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;integer&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nn"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="c"&gt;%% 把X存为有符号小端整数, 大小为 4*8 bit
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;integer&lt;/span&gt; &lt;span class="c"&gt;%% 把A存储为32位整数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;B&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;binary&lt;/span&gt; &lt;span class="c"&gt;%% 要求B是长于或等于15字节的二进制串, 截取B的前15字节
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;变量:大小/类型&lt;/code&gt; 的格式中, 大小和类型是可以省略的, 因此可以有:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;变量:大小
变量/类型
变量
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;当进行省略时, 会使用默认值:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;缺省的类型是整数 ( &lt;a class="link" href="http://www.erlang.org/doc/programming_examples/bit_syntax.html" target="_blank" rel="noopener"
 &gt;手册&lt;/a&gt;
上的例子是有点问题的, &amp;laquo;3.14&amp;raquo;这样的写法在 Erlang 16B 版上是非法的).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;缺省的大小与类型有关:&lt;/p&gt;
&lt;p&gt;整数是8位, &lt;em&gt;溢出部分被截掉&lt;/em&gt;: 例如&lt;code&gt;&amp;lt;&amp;lt; 257 &amp;gt;&amp;gt;&lt;/code&gt;等价于&lt;code&gt;&amp;lt;&amp;lt; 257:8 &amp;gt;&amp;gt;&lt;/code&gt;, 值等于&lt;code&gt;&amp;lt;&amp;lt; 1 &amp;gt;&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;浮点数是64位&lt;/p&gt;
&lt;p&gt;二进制串是整个串的长度: 例如&lt;code&gt;&amp;lt;&amp;lt; A/binary &amp;gt;&amp;gt;&lt;/code&gt;会把整个A都存起来.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;对于整数, 缺省是无符号的.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;对于整数, 缺省是大端的(big-endian).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;可以使用 &lt;code&gt;-unit:长度&lt;/code&gt; 的方式来指定单位长度, 缺省的单位长度与类型有关.&lt;/p&gt;
&lt;p&gt;整数(integer)/浮点数(float)/字节串(bitstring) 的缺省长度是1.&lt;/p&gt;
&lt;p&gt;而binary类型缺省长度是8.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;二进制的连接直接在&lt;code&gt;&amp;lt;&amp;lt; &amp;gt;&amp;gt;&lt;/code&gt;中使用逗号放一起就可以了, 例如&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-erlang" data-lang="erlang"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;B&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;binary&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1234&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;String&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;中文也可以&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;引号的后面不能加/binary&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;但是二进制串中括另一个二进制串要指定格式&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;binary&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;其它的二进制语法, 例如二进制中的模式匹配/二进制解析, 等等, 就不在这里讲了.&lt;/p&gt;
&lt;p&gt;参考:&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="http://www.erlang.org/doc/programming_examples/bit_syntax.html" target="_blank" rel="noopener"
 &gt;官方手册&lt;/a&gt;&lt;/p&gt;</description></item></channel></rss>