为什么 erlang 中此字符串的模式匹配会导致尾部出现"string",列表出现 ascii 值?



我试图用 erlang 编写一个模式匹配函数,如下所示:

to_end("A") -> "Z".

整个想法是使用模式匹配函数将字符串(如"ABC")转换为不同的字符串(如"ZYX")。看起来字符串在引擎盖下表示为列表...

我依赖于这样一个事实,即 erlang 中"字符串"上的模式匹配将导致单个字符串字符。但我发现这个:

21> F="ABC".
22> F.
"ABC"
23> [H | T]=F.
"ABC"
24> H.
65
25> T.
"BC"

为什么列表上这种类型的模式匹配的头部总是产生 ASCII 值,而尾部总是产生字母?有没有更好的方法来对"字符串列表"进行模式匹配?

在 Erlang 中,字符串只是 ascii 值的列表。它还以字符串形式显示整数列表,其中每个整数都是可打印的 ASCII 代码。所以[48, 49]会打印出"01",因为 48 对应于0,49 对应于1.由于你有字符串"ABC",这与[65 | [66 | [67]]]相同,[66, 67]将显示为"BC"

如果要编写函数来对字符进行模式匹配,则应使用字符文本语法,该语法$后跟字符。所以你会写

to_end($A) -> $Z;
to_end($B) -> $Y;
to_end($C) -> $X;
...
to_end($Z) -> $A.

而不是与to_end([65]) -> [90]相同的to_end("A") -> "Z".

为什么这种类型的模式的头部总是在列表中匹配 结果为 ASCII 值,尾部结果为字母?

在 erlang 中,字符串"ABC"是列表[65,66,67]的简写表示法。 该列表的头部是65,而该列表的尾部是列表[66,67],shell恰好显示为"BC"。 哇??!

外壳在显示字符串/列表时非常糟糕:有时外壳显示列表,有时外壳显示双引号字符串:

2> [0, 65, 66, 67].
[0,65,66,67]
3> [65, 66, 67].
"ABC"
4> 

。这简直是愚蠢的。 每个初级和中级 erlang 程序员都会在某个时候对此感到困惑。

请记住:当 shell 显示双引号字符串时,它实际上应该显示一个列表,其元素是双引号字符串中每个字符的字符代码。 外壳显示双引号字符串的事实很糟糕??特征??的 erlang,这使得在很多情况下很难破译正在发生的事情。 你必须在心里对自己说,"我在壳中看到的那根绳子真的是清单......">

当您想要显示一个人的测试分数列表时,shell 在某些列表中显示双引号字符串这一事实真的很糟糕:[88, 97, 92, 70]和 shell 输出:"Xa\F"。 您可以使用io:format()方法来解决此问题:

6> io:format("~w~n", [[88,97,92,70]]).
[88,97,92,70]
ok

但是,如果您只想暂时查看 shell 显示为字符串的实际整数列表,一种快速而肮脏的方法是将整数0添加到列表的头部:

7> Scores = [88,97,92,70].
"Xa\F"

哼?!!

8> [0|Scores].
[0,88,97,92,70]

哦,好的。

整个想法是将诸如"ABC"之类的字符串转换为某些东西 不同的是,例如使用模式匹配函数的"ZYX"。

由于字符串是整数列表的简写,因此可以使用 addition:

-module(my).
-compile(export_all).
cipher([]) -> [];
cipher([H|T]) ->
[H+10|cipher(T)].  %% Add 10 to each character code.

在外壳中:

~/erlang_programs$ erl
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V9.3  (abort with ^G)
1> c(my).
my.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,my}
2> my:cipher("ABC").
"KLM"
3>

顺便说一下,所有函数都是"模式匹配"的,所以说"模式匹配函数"是多余的,你可以说"一个函数"。

最新更新