Erlang:没有右手边的值匹配

时间:2014-05-10 06:36:41

标签: erlang pattern-matching

Erlang程序中的常见错误消息如下:

** exception error: no match of right hand side value 'foo'
     in function module:function/2 (file.erl, line 42)

我该如何调试?

2 个答案:

答案 0 :(得分:6)

以下是调试此类错误的方法:

  1. 转到module:function/2 (file.erl, line 42)

  2. 找到肯定存在的违规匹配操作

  3. 新鲜变量替换左侧。在这里,您可能会发现您正在尝试与已绑定的变量进行模式匹配...

  4. 使用新变量

  5. 添加对erlang:display/1的调用
  6. 再次运行程序以打印此变量的值并理解它与给定模式不匹配的原因

  7. 以下是一些例子:

    • Example 1

      {_, Input} = io:get_line("Do you want to chat?") % Line 42
      

      将其替换为:

      Fresh1 = io:get_line("Do you want to chat?"),
      erlang:display(Fresh1),
      {_, Input} = Fresh1
      

      再次运行程序:

      1> module:run().
      Do you want to chat? Yes
      "Yes\n"
      ** exception error: no match of right hand side value "Yes\n"
        in function module:function/2 (file.erl, line 44)
      

      您可以看到io:get_line/1返回字符串而不是元组,因此与{_, Input}的匹配失败。

    • Example 2

      在Erlang shell中:

      2> Pid = echo:start().
      ** exception error: no match of right hand side value <0.41.0>
      

      此处变量Pid肯定已经绑定到另一个值...

      3> Pid.
      <0.39.0>
      

      您可以通过f(Var)f()

      让shell忘记此类绑定
      4> f(Pid).
      ok
      5> Pid.
      * 1: variable 'Pid' is unbound
      6> Pid = echo:start().
      <0.49.0>
      

答案 1 :(得分:2)

错误报告比简单的坏匹配更友好,它也给出了无法匹配的值。如果这个值是&#34;小&#34;足够,它完全显示,通常足以了解出现了什么问题:

-module(err).

-export([test/0]).

test() ->
    "ok\n" = io:get_line("an input ? ").

test2() ->
    F = fun() ->
        "ok\n" = io:get_line("an input ? ")
    end,
    F().
shell中的

1> c(err).
{ok,err}
2> err:test().
an input ? ok
"ok\n"
3> err:test().
an input ? ko
** exception error: no match of right hand side value "ko\n"
     in function  err:test/0 (err.erl, line 6)
4> F = fun() -> a = 10 end.
#Fun<erl_eval.20.106461118>
5> F().
** exception error: no match of right hand side value 10
6> err:test2().
an input ? ok
"ok\n"
7> err:test2().
an input ? ko
** exception error: no match of right hand side value "ko\n"
     in function  err:'-test2/0-fun-0-'/0 (err.erl, line 10)
8>