【问题标题】:confusion regarding erlang maps, lists and ascii关于 erlang 映射、列表和 ascii 的混淆
【发布时间】:2014-09-15 01:21:27
【问题描述】:

此代码摘自此book

count_characters(Str) ->
    count_characters(Str, #{}).

count_characters([H|T], #{ H => N }=X) ->
    count_characters(T, X#{ H := N+1 });
count_characters([H|T], X) ->
    count_characters(T, X#{ H => 1 });
count_characters([], X) ->
    X.

所以,

1> count_characters("hello").
#{101=>1,104=>1,108=>2,111=>1}

我从中了解到的是,count_characters() 接受一个参数 hello,并将其放在第一个函数中,即 count_characters(Str)

我不明白的是,字符串字符是如何在不使用$的情况下转换为ascii值并递增的。我对 erlang 很陌生,如果您能帮助我理解上述内容,我将不胜感激。谢谢。

【问题讨论】:

    标签: erlang


    【解决方案1】:

    在 erlang 中,字符串文字 "hello" 只是编写列表 [104,101,108,108,111] 的一种更方便的方式。字符串格式是语法糖,erlang 内部一无所知。 ascii 字符串是内部字符串,内部存储为 32 位整数列表。

    当打印值恰好在 ascii 范围内的列表时,这也会变得令人困惑:

    io:format("~p~n", [[65,66]]).
    

    将打印

    "AB"
    

    即使你没想到结果是字符串。

    【讨论】:

    • 是的,erlang 既没有字符数据类型也没有字符串数据类型。整数字符值通常是 unicode 代码点,而不仅仅是 ascii 值。
    【解决方案2】:

    如前所述,Erlang中没有字符串数据类型,它使用整数列表的内部表示,所以

    "hello" == [$h,$e,$l,$l,$o] == [104|[101|[108|[108|[111|[]]]]]]

    它们都是整数列表的有效表示。

    为了计算字符数,该函数使用了一种新的 Erlang 数据类型:映射。 (仅从 R17 开始可用)

    地图是键/值对的集合,在您的情况下,键是字符,值是每个字符的出现。

    使用空映射调用该函数:count_characters(Str, #{})

    然后递归遍历列表,对于每个头H,可能有2种情况:

    • 已经找到字符H,那么当前映射X将匹配模式#{ H => N }告诉我们已经找到NH,所以我们继续递归其余的列表和一个新地图,其中与 H 关联的值现在是 N+1count_characters(T, X#{ H := N+1 }
    • 第一次找到字符H,然后我们继续递归列表的其余部分和一个新的映射,其中添加了键/值对H/1count_characters(T, X#{ H => 1 })

    到达列表末尾时,只需返回地图:count_characters([], X) -> X.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-30
      • 1970-01-01
      • 1970-01-01
      • 2012-02-08
      • 1970-01-01
      相关资源
      最近更新 更多