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

Why does pattern matching on this string in erlang result in a "string" for the tail and an ascii value for the list?

我试图在 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值而尾部结果为字母?有没有更好的方法来对 "list of string" 进行模式匹配?

在 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].

相同

Why does the head of this type of pattern matching on list always result in an ASCII value and the tail result in letters?

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

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

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

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

4> 

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

请记住:当shell显示双引号字符串时,它实际上应该显示一个列表,其元素是双引号字符串中每个字符的字符代码。 shell 显示双引号字符串的事实是一个糟糕的??特性?? erlang,这使得在很多情况下很难破译正在发生的事情。你必须在心里对自己说,"That string I'm seeing in the shell is really the list ..."

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]

哦,好的。

The whole idea is to transform a string such as "ABC" into something different such as "ZYX" using pattern matched functions.

因为字符串是 shorthand 整数列表,您可以使用加法更改这些整数:

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

顺便说一句,所有的功能都是"pattern matched",所以说"a pattern matched function"是多余的,你可以说,"a function".