为什么在erlang中对该字符串进行模式匹配会导致结尾的“字符串”和列表的ascii值?

时间:2019-04-28 05:28:31

标签: erlang

我试图用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值,而尾部导致字母呢?有没有更好的方法来对“字符串列表”进行模式匹配?

2 个答案:

答案 0 :(得分:3)

在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("A") -> "Z"的{​​{1}}。

答案 1 :(得分:0)

  

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

在erlang中,字符串"ABC"是列表[65,66,67]的简写形式。该列表的开头是65,列表的结尾是列表[66,67],shell恰好将其显示为"BC"。哇!!

在显示字符串/列表时,shell很烂:有时,shell显示列表,有时,shell显示双引号的字符串:

2> [0, 65, 66, 67].
[0,65,66,67]

3> [65, 66, 67].
"ABC"

4> 

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

请记住:当外壳程序显示双引号字符串时,它实际上应该显示一个列表,其元素是双引号字符串中每个字符的字符代码。外壳显示双引号字符串的事实是一个可怕的“功能”。 erlang,这使得在很多情况下难以理解正在发生的事情。您必须在心里对自己说:“我在shell中看到的字符串确实是列表...”

当您要显示某人的考试成绩列表[88, 97, 92, 70]而shell输出"Xa\\F"时,shell在某些列表上显示双引号字符串的事实确实很糟糕。您可以使用io:format()方法来解决此问题:

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

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

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

嗯?!

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

哦,好吧。

  

整个想法是将诸如“ ABC”之类的字符串转换成某种东西   例如使用模式匹配功能的“ ZYX”。

因为字符串是整数列表的简写形式,所以可以使用加法来更改这些整数:

-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>

顺便说一下,所有功能都是“模式匹配的”,所以说“模式匹配的功能”是多余的,您可以说“一个功能”。