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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么在erlang中对此字符串进行模式匹配会导致尾部的“字符串”和列表的ascii值?相关的知识,希望对你有一定的参考价值。

我试图在erlang中编写模式匹配函数,如:

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

整个想法是使用模式匹配函数将诸如“ABC”之类的字符串转换为不同的字符串,例如“ZYX”。它看起来像一个字符串被表示为引擎盖下的列表......

我依赖于在erlang中“string”上的模式匹配会导致单个字符串字符这一事实。但我发现这个:

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("A") -> "Z",它与to_end([65]) -> [90]相同。

另一答案

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

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

显示字符串/列表时,shell非常糟糕:有时shell会显示一个列表,有时shell会显示一个双引号字符串:

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

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

4> 

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

请记住:当shell显示双引号字符串时,它应该显示一个列表,其元素是双引号字符串中每个字符的字符代码。 shell显示双引号字符串的事实是一个可怕的特性??对于erlang而言,它很难解读在很多情况下发生的事情。你必须在精神上对自己说,“我在shell中看到的字符串真的是列表...”

当你想要显示一个人的测试分数列表时,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”。

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

-module(my).
-compile(export_all).

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

在shell中:

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

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

以上是关于为什么在erlang中对此字符串进行模式匹配会导致尾部的“字符串”和列表的ascii值?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 OCaml 模式匹配比 Erlang 弱?

Erlang中二进制字符串的棘手模式匹配

为啥 Erlang 中的模式匹配记录会抛出错误

Erlang中模式匹配字符串的正确方法

模式匹配 Erlang 字符串作为函数中的列表

在erlang中列出尾部模式匹配