我使用list comprehension将数据库行从元组列表转换为映射列表。有一天,我在我的数据库表中添加了一些新列,忘了在任何地方更改代码。 因此我发现了一个奇怪的效果:数据库行变成一个空列表。
erl控制台中的代码示例:
> DbRows = [{1, 1, 1}, {2, 2, 2}].
[{1,1,1},{2,2,2}]
> [#{<<"col1">> => Col1, <<"col2">> => Col2} ||{Col1, Col2} <- DbRows].
[]
为什么Erlang在这种情况下不会生成异常错误:右侧值不匹配?
此代码是否正常,或者首选其他语法来执行此类数据转换?
答案 0 :(得分:5)
Erlang不会生成任何异常,因为它是正确的语法。生成器{Col1, Col2} <- DbRows
同时是一个过滤器。因此,任何与模式不匹配的元素都会被跳过。
在你的情况下,我会做这样的事情:
-define(FIELDS, [id, some1, some2]).
DbRows = [{1, 1, 1}, {2, 2, 2}].
Prepare = fun(X) ->
maps:from_list(lists:zip(?FIELDS, tuple_to_list(X)))
end.
[ Prepare(Row) || Row <- DbRows].
当您添加新字段时,您需要在宏中添加该字段。
答案 1 :(得分:1)
我不喜欢这个“功能”,因为根据我的经验,它往往会掩盖错误,但是nikit的答案对于你看到的结果的原因是正确的。
您可以通过将模式匹配移动到列表推导的左侧来获取异常:
[ case Row of {Col1, Col2} -> #{<<"col1">> => Col1, <<"col2">> => Col2} || Row <- DbRows ]