调用Complex.complex_to_string(0,4)触发:erlang.bit_size(nil)错误的原因及解决
问题解答:Complex.complex_to_string/2 参数为0时的错误分析与修复
错误产生的核心原因
当你传入r=0时,这段代码触发了问题:
to_str = to_str <> if r != 0 do "#{r}" end
在Elixir中,不带else分支的if语句,当条件不满足时会返回nil。所以当r=0时,if r !=0 do ... end的结果是nil,而字符串拼接操作<>要求左右两侧必须都是字符串类型。把nil和字符串拼接时,底层Erlang会尝试调用:erlang.bit_size/1获取参数的位大小,但nil没有这个属性,于是就抛出了ArgumentError。
能不能以0作为第一个参数调用函数?
当然可以!这个问题只是原代码的逻辑漏洞导致的,只要补上默认分支,就能正常处理r=0的情况。
修复方案
你自己在编辑里给出的方案就很正确——把原来的if替换成带默认分支的cond,确保无论r是否为0,都返回一个字符串(空字符串也可以),避免返回nil。修复后的完整代码如下:
defmodule Complex do def complex_to_string(r, i) do to_str = "" to_str = to_str <> cond do r != 0 -> "#{r}" true -> "" end to_str = to_str <> cond do i < 0 or (r == 0 and i != 0) -> "#{i}i" i > 0 -> "+#{i}i" :true -> "" end to_str end end
或者也可以给原来的if加上else分支,效果是一样的:
to_str = to_str <> if r != 0 do "#{r}" else "" end
测试修复后的代码,就能正常处理r=0的场景了:
iex> Complex.complex_to_string(0, 4) "4i" iex> Complex.complex_to_string(0, -2) "-2i" iex> Complex.complex_to_string(0, 0) ""
内容的提问来源于stack exchange,提问作者karlosos
相关产品推荐
相关产品推荐

