模式识别

模式识别被用于变量赋值和程序流程控制。Erlang是一种单性赋值语言,即一个变量一旦被赋值,就再也不可改变。

模式识别用于将模式与项式进行匹配。如果一个模式与项式具备相同的结构则匹配成功,并且模式中的所有变量将被绑定到项式中相应位置上出现的数据结构。

函数调用中的模式识别

程序1.4定义了在摄氏、华氏和列式温标间进行温度转换的函数convertconvert的第一个参数是一个包含了温标和要被转换的温度值,第二个参数是目标温标。

程序1.4

  1. -module(temp).
  2. -export([convert/2]).
  3.  
  4. convert({fahrenheit, Temp}, celsius) ->
  5. {celsius, 5 * (Temp - 32) / 9};
  6. convert({celsius, Temp}, fahrenheit) ->
  7. {farenheit, 32 + Temp * 9 / 5};
  8. convert({reaumur, Temp}, celsius) ->
  9. {celsius, 10 * Temp / 8};
  10. convert({celsius, Temp}, reaumur) ->
  11. {reaumur, 8 * Temp / 10};
  12. convert({X, _}, Y) ->
  13. {cannot,convert,X,to,Y}.

convert进行求值时,函数调用中出现的参数(项式)与函数定义中的模式进行匹配。当找到一个匹配时,“->”右侧的代码便被求值,如:

  1. > temp:convert({fahrenheit, 98.6}, celsius).
  2. {celsius,37.0000}
  3. > temp:convert({reaumur, 80}, celsius).
  4. {celsius,100.000}
  5. > temp:convert({reaumur, 80}, fahrenheit).
  6. {cannot,convert,reaumur,to,fahrenheit}

匹配原语“=”

表达式Pattern=Expression致使Expression被求值并尝试与\ Pattern 进行匹配。匹配过程要么成功要么失败。一旦匹配成功,则Pattern中所有的变量都被绑定,例如:

  1. > N = {12, banana}.
  2. {12,banana}
  3. > {A, B} = N.
  4. {12,banana}
  5. > A.
  6. 12
  7. > B.
  8. banana

匹配原语可用于从复杂数据结构中拆分元素。

  1. > {A, B} = {[1,2,3], {x,y}}.
  2. {[1,2,3],{x,y}}
  3. >A.
  4. [1,2,3]
  5. >B.
  6. {x,y}
  7. > [a,X,b,Y] = [a,{hello, fred},b,1].
  8. [a,{hello,fred},b,1]
  9. > X.
  10. {hello,fred}
  11. > Y.
  12. 1
  13. > {_,L,_} = {fred,{likes, [wine, women, song]},
  14. {drinks, [whisky, beer]}}.
  15. {fred,{likes,[wine,women,song]},{drinks,[whisky,beer]}}
  16. > L.
  17. {likes,[wine,women,song]}

下划线(写作“_”)代表特殊的匿名变量或无所谓变量。在语法要求需要一个变量但又不关心变量的取值时,它可用作占位符。

如果匹配成功,定义表达式Lhs=Rhs的取值为Rhs。这使得在单一表达式中使用多重匹配成为可能,例如:

  1. {A, B} = {X, Y} = C = g{a, 12}

=”是右结合操作符,因此A=B=C=D被解析为A=(B=(C=D))