为什么我从Erlang翻译的Elixir程序中收到FunctionClauseError(“无函数子句匹配”)?

时间:2015-06-12 22:26:37

标签: erlang elixir variable-names

**所以,我之前和Erlang一起工作过,而且我很熟悉它。我只是想学习Elixir。

我最近试图将一个'懒惰的caterers'示例翻译成elixir,并且为什么它要么不编译,要么编译警告并且不起作用,我感到很困惑。我在这里缺少什么;有任何想法吗? erlang代码和'run'如下:**

jps@GRASSKEET ~/dev/erlang
$ cat cater.erl

    -module(cater).
    -export([cater/1]).
    cater(0) -> 1;
    cater(N) when N>0 -> N + cater(N-1).

jps@GRASSKEET ~/dev/erlang
$ erl
Eshell V6.3  (abort with ^G)
1> c("cater.erl").
{ok,cater}
2> cater:cater(10).
56
3>*

当我像这样编写Cater.ex时,会出现一个对我没有意义的错误:

jps@GRASSKEET ~/dev/elix
$ cat Cater.ex

    defmodule Cater do
      def cut(0), do: 1
      def cut(N) when N>0, do: N + cut(N-1)
    end

jps@GRASSKEET ~/dev/elix
$ iex
Interactive Elixir (1.0.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> c("Cater.ex")
Cater.ex:1: warning: redefining module Cater
Cater.ex:3: warning: this expression will fail with ArithmeticError
[Cater]
iex(2)> Cater.cut(10)
** (FunctionClauseError) no function clause matching in Cater.cut/1
    Cater.ex:2: Cater.cut(10)
iex(2)>

1 个答案:

答案 0 :(得分:8)

只是为了扩展问题以及您收到错误的原因:

大写标识符被视为原子的别名。例如:

iex(1)> N == :Elixir.N
true

所以当你有以下代码时:

iex(1)> defmodule Test do
...(1)> def foo, do: IO.puts "testing"
...(1)> end
iex(2)> Test.foo
testing

与说

相同
iex(3)> :Elixir.Test.foo
testing

由于大写标识符被视为符号,因此您基本上编写了以下程序:

defmodule Cater do
  def cut(0), do: 1
  def cut(:Elixir.N) when :Elixir.N>0, do: :Elixir.N + cut(:Elixir.N-1)
end

这是有效的,因为您可以在参数列表中对原子进行模式匹配,:Elixir.N > 0是一个有效的表达式。

iex(1)> N > 0
true

考虑以下Elixir程序和输出:

iex(1)> defmodule Cater do
...(1)> def cut(0), do: IO.puts "cut(0)"
...(1)> def cut(N) when N > 0, do: IO.puts "cut(N)"
...(1)> end
iex(2)> Cater.cut(0)
cut(0)
iex(3)> Cater.cut(N)
cut(N)
iex(4)> Cater.cut(:Elixir.N)
cut(N)
iex(5)> Cater.cut(1)
** (FunctionClauseError) no function clause matching in Cater.cut/1
    iex:2: Cater.cut(1)

所以,你得到看似奇怪的错误消息no function clause matching in Cater.cut/1的原因是你的程序在技术上没有任何问题(除cut(N)的实际函数体外 - 它会引发ArithmeticError },Elixir在编译时警告你);它完全有效,它不会做你想做的事情/你认为它做了什么。