Erlang map 中的非法匹配问题

《Programming Erlang》第 5 章有个例子。
通过 map 计算字符串各个字符出现的频率。

代码如下

-module(countChar).
-export([count_characters/1]).

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.

运行后一直报错:

错误

找了好一会也没找到错误,于是网上查说是版本错误。

版本
Erlang/OTP 17 [erts-6.2] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V6.2 (abort with ^G)

最新版本是Erlang/opt 18.1,我的是Erlang/opt 17

跑到 官网 下载最新版本,发现官网根本进不去,进去也下载不了,网上有人说 Erlang 的官网在瑞典,速度慢的根本不能下载- -,于是跑到群里求助,有个好心的前辈给我发了Erlang 18.1 最新版本。

我传到了云盘上,需要的小伙伴可以去下载哈~
windows Erlang/opt 18.1
Linux Erlang/opt 18.1

然后卸载 17 安装 18。
编译,运行
又出现了如下错误:

这里写图片描述

应该还是版本问题,但是没有找到相关资料,最后在 StackOverFlow 找到了相同的问题。

查了相关资料,得知:
在 Erlang/opt 17中
- No variable keys (key中不能含变量)
- No single value access (不支持取单个value,即不支持#{Key}操作)
- No map comprehensions (不支持map推导,例如 #{X => foggy || X <- [london,boston]}.)

18 中仅得到部分支持

如果我们要使用上述功能,应该运用 Erlang 提供给我们的 maps 模块。

maps:new()
erlang:is_map(M)
maps:is_key(Key, Map)
maps:get(Key, Map)

最后答主贴了 17 版本和 18 版本下可运行的例子:

Erlang/opt 17 版本

-module(count_chars).
-export([count_characters/1]).

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

%% maps module functions cannot be used as guards (release 17)
%% or you'll get "illegal guard expression" error
count_characters([H|T], X) ->
    case maps:is_key(H,X) of
        false -> count_characters(T, maps:put(H,1,X));
        true  -> Count = maps:get(H,X),
                         count_characters(T, maps:update(H,Count+1,X))
    end;
count_characters([], X) ->
        X.

Erlang/opt 18 版本

-module(count_chars).
-export([count_characters/1]).

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

count_characters([H|T], X) ->
    case maps:is_key(H,X) of
        false -> count_characters(T, X#{ H => 1 });
        true  -> #{ H := Count } = X,
                 count_characters(T, X#{ H := Count+1 })
    end;
count_characters([], X) ->
        X.

可见 17 版本中全部使用了 maps 模块中的 API,18 版本只用了 maps:is_key()。

我自己尝试运行 Erlang/opt 18 版本,成功。

这里写图片描述

书中作者的写法可能会在将来版本中支持。
毕竟看起来简洁多了^_^。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏天的技术博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值