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 map 中的非法匹配问题_第1张图片

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

版本 
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 版本,成功。

这里写图片描述

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

========================================

hzhsan注:上面内容转自http://blog.csdn.net/wwh578867817/article/details/49744285

和他经历了同样的坎,灰常感谢作者的分享,在这里就偷懒直接转过来了。

你可能感兴趣的:(erlang,Pattern,map,Illegal)