Elixir更新列表尾元素触发算术错误问题求助
Elixir Map列表值第二个元素更新问题解决指南
嘿,刚看到你的问题啦,作为Elixir和函数式编程的新手,遇到这种模式匹配的小坑太正常了,我来给你掰扯清楚~
首先咱们先分析你为啥会报错:你用[a|b]这个模式匹配列表的时候,|的作用是把列表拆成首元素和剩余的子列表,不是拆成两个单独的元素哦!比如你的目标列表是[1,0],匹配[a|b]后,a会是1,而b是[0](注意这是个只有一个元素的列表,不是单个整数0)。所以你写b+1的时候,本质是在让一个列表和整数做加法,Elixir当然会抛出ArithmeticError啦!
先回顾你的错误代码和报错
你尝试更新第二个元素的代码:
iex(3)> a = Map.update!(a, 'b', fn([a|b]) -> a ++ [b+1] end)
对应的报错信息:
** (ArithmeticError) bad argument in arithmetic expression
:erlang.+([0], 1)
(stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
(stdlib) erl_eval.erl:228: :erl_eval.expr/5
(stdlib) erl_eval.erl:470: :erl_eval.expr/5
(elixir) lib/map.ex:727: Map.update!/3
正确的解决方案
既然你明确说列表固定是2个元素,那咱们直接用更精准的模式匹配,把列表拆成两个独立的元素:
更新第二个元素的代码
# 先初始化你的Map iex(1)> a = %{'b' => [1, 0]} # 更新第二个元素 iex(2)> a = Map.update!(a, 'b', fn([first, second]) -> [first, second + 1] end) # 查看结果 iex(3)> a['b'] [1, 1]
顺带优化下第一个元素的更新写法
你之前更新第一个元素的代码是可行的,但也可以用同样清晰的模式匹配来写,逻辑更直观:
iex(2)> a = Map.update!(a, 'b', fn([first, second]) -> [first + 1, second] end)
这样不管是更新第一个还是第二个元素,代码逻辑一目了然,也不会再出现模式匹配的错误啦~
内容的提问来源于stack exchange,提问作者hack-is-art
相关产品推荐
相关产品推荐

