为啥 Erlang 中的模式匹配记录会抛出错误
Posted
技术标签:
【中文标题】为啥 Erlang 中的模式匹配记录会抛出错误【英文标题】:Why does pattern matching records in Erlang throw error为什么 Erlang 中的模式匹配记录会抛出错误 【发布时间】:2019-12-13 06:33:54 【问题描述】:您好,我正在尝试使用 Erlang 中的记录语法将变量绑定到封闭记录及其字段之一,但我不断收到此错误:
d:/Erlang/AeRlang/rec.erl:19: 之前的语法错误:子
d:/Erlang/AeRlang/rec.erl:17: 函数 isMale/1 未定义
d:/Erlang/AeRlang/rec.erl:17: 警告:函数 maleChildren/1 是 未使用
-module(rec).
-export([makeFam/0]).
-record(man,name,
age,
children=[]).
-record(child,
name,
age,
sex
).
makeFam()->
#manname="Adrian",
age=33,
children=[#childname="Daniel",age=33,sex="Male",
#childname="Chris" ,sex="Male",
#childname="Anne",age=33,sex="Female"]
.
fatherAndSons(Man#manchildren=Ch)->Man,[Elem|| Elem<-Ch,isMale(Elem)].
isMale(C#child_,_,Y)->
case Y of
"Male"->true;
_ ->false
end.
我的isMale
方法有什么问题。我将封闭结构#child
绑定到变量C
,并且我也在对其字段进行模式匹配。有什么问题?
P.S:这是否与在isMale
方法中我没有指定绑定变量Y
的字段的名称有关?
【问题讨论】:
【参考方案1】:在您的child record
中获取sex
的方式存在一些错误。您可以更改您的函数fatherAndSons/1
和isMale/1
,如下所示:
fatherAndSons(Man#manchildren=Ch)->Man,[Elem|| Elem<-Ch,isMale(Elem) == true].
isMale(C)->
case C#child.sex of
"Male"->true;
_ ->false
end.
或者只是删除您的isMale/1
和列表理解中的模式匹配:
fatherAndSons(Man#manchildren=Ch)->
Man, [Elem || Elem <-Ch, Elem#child.sex == "Male"].
【讨论】:
但是为什么会出现问题,因为我直接在isMale
参数上绑定变量,然后在case
子句中绑定时对其进行模式匹配。出了什么问题?
case
子句中的模式匹配没有错。在记录child
中获取变量Y
的方式是错误的。只能将isMale(C#child_,_,Y)->
这一行改成isMale(#childsex = Y)->
【参考方案2】:
对于fatherAndSons/1
和isMale/1
函数,您使用错误的语法将记录匹配为函数参数。以下是一些更正的版本:
fatherAndSons(Man=#manchildren=Ch) -> Man, [Elem || Elem <- Ch, isMale(Elem)].
isMale(#childsex="Male")-> true;
isMale(_) -> false.
在fatherAndSons/1
的函数头中,我们基本上是在说“Man
应该是一个#man
记录,我们将绑定到children
字段的Ch
”。 =
运算符是匹配的,但您在 Man
绑定中缺少它。
对于isMale/1
,我使用了两个子句,其中第一个子句匹配所有#child
记录,其sex
字段匹配字符串"Male"
,第二个子句匹配其他任何内容。如果您想将第二个子句限制为仅匹配 #child
记录,您可以改用:
isMale(#childsex="Male")-> true;
isMale(#child) -> false.
无论哪种方式,请注意无需将记录绑定到函数头中的变量isMale/1
,因为您不需要在函数体中进行绑定。
【讨论】:
但是我没有使用=
,因为这是在模式匹配整个结构时出现在Learn you a Erlang for great good 中的方式,尽管不是作为函数参数而是在方法内部。 (查看方法repairman
)
在您引用的repairman
函数中,Details = Rob#robot.details
行的意思是“将Details
绑定到details
字段的值Rob
,这是一个实例#robot
记录。”换句话说,在这种情况下,Rob
已经绑定到 #robot
记录,这与您尝试将 Man
绑定到函数头中的 #man
记录不同。
感谢您的详尽解释!以上是关于为啥 Erlang 中的模式匹配记录会抛出错误的主要内容,如果未能解决你的问题,请参考以下文章
为啥雪花 jdbc 会抛出 [XX000][200001] 错误
为啥 toPandas() 会抛出错误,而 .show() 工作得很好?
为啥 `"foo".bar = 42;` 在 ES6 的严格模式下会抛出 `TypeError`?