将 :d iscard 传递给 Enum.chunk_every 时出现 FunctionClauseError

FunctionClauseError when passing :discard to Enum.chunk_every

提问人:Maninder Singh Rehalan 提问时间:11/4/2023 最后编辑:Adam MillerchipManinder Singh Rehalan 更新时间:11/5/2023 访问量:48

问:

所以我一直在做一个udemy课程来学习长生不老药,我应该在其中列出并创建包含长度为3的值列表的新列表

这是我的旧清单

[23, 137, 4, 86, 54, 223, 37, 191, 22, 167, 25, 238, 102, 56, 39, 4]

我想把它转换成这个

[[23, 137, 4],[ 86, 54, 223],[ 37, 191, 22],[ 167, 25, 238],[ 102, 56, 39]]

我的代码

  def main(name) do
    name
    |> hash
    |> pickColor
    |> buildGrid
  end

  def buildGrid(%Identicon.Image{hex: hex}=image) do
    hex
    |>Enum.chunk_every(3, :discard)
  end

  def pickColor(%Identicon.Image{hex: [r,g,b | _tail]} = image) do
     %Identicon.Image{image | color: {r,g,b}}
  end

  def hash(name) do
    hex = :crypto.hash(:md5,name)
    |> :binary.bin_to_list()
    %Identicon.Image{hex: hex}
  end

我得到的响应是

** (FunctionClauseError) no function clause matching in Enum.chunk_every/4

    The following arguments were given to Enum.chunk_every/4:

        # 1
        [23, 137, 4, 86, 54, 223, 37, 191, 22, 167, 25, 238, 102, 56, 39, 4]

        # 2
        3

        # 3
        :discard

        # 4
        []

    Attempted function clauses (showing 1 out of 1):

        def chunk_every(enumerable, count, step, leftover) when is_integer(count) and count > 0 and is_integer(step) and step > 0

    (elixir 1.15.0) lib/enum.ex:547: Enum.chunk_every/4
    (identicon 0.1.0) lib/identicon.ex:23: Identicon.buildGrid/1
    iex:6: (file)
炼金药

评论


答:

2赞 Adam Millerchip 11/4/2023 #1

您正在执行以下操作:

iex> Enum.chunk_every(list, 3, :discard)
** (FunctionClauseError) no function clause matching in Enum.chunk_every/4

但是您需要这样做:

iex> Enum.chunk_every(list, 3, 3, :discard)
[[23, 137, 4], [86, 54, 223], [37, 191, 22], [167, 25, 238], [102, 56, 39]]

实际上有三种形式的Enum.chunk_every

  1. 双参数形式:Enum.chunk_every/2,是三参数参数形式:→的快捷方式,其中 也作为第三个参数传递。chunk_every(list, count)chunk_every(list, count, count)countstep
  2. 三参数形式:Enum.chunk_every/4,实际上是四参数形式,其中第四个参数的默认值是空列表:→ 。这与双参数形式不同,因为它不是可选的。leftoverchunk_every(list, count, step)chunk_every(list, count, step, [])step
  3. 四参数形式,与三参数形式相同,但具有显式值 。leftover

您的代码正在执行 ,尝试作为第四个参数传递,但没有传递所需的第三个参数。所以 Elixir 正确地抱怨这个函数没有接受参数的版本。解决方法是传递所需的第三个参数,其值与 相同。Enum.chunk_every(enum, 3, :discard):discardleftoverstep(list, integer, atom)stepcount

这很令人困惑,因为双参数版本允许 to default to automation(并且通过扩展,默认为 automatly),但四参数版本要求您显式传递,同时仍然允许参数是可选的。stepcountleftover[]stepleftover

评论

0赞 Maninder Singh Rehalan 11/4/2023
然后我偶然发现了另一个错误,当我在 sert ' iex> Enum.chunk_every(list, 3, 3, :d iscard)' 中返回值与我预期的不同。' [[23, 137, 4], [86, 54, 223], [37, 191, 22], [167, 25, 238], ~c“f8'”] ' 我的最后一个块怎么了?
0赞 Aleksei Matiushkin 11/4/2023
你的最后一个块什么也没发生。.有关进一步的解释,请参见 stackoverflow.com/questions/40324929/...'f8\'' == [102, 56, 39] #⇒ true
0赞 Maninder Singh Rehalan 11/4/2023
@AlekseiMatiushkin,谢谢你的链接,非常感谢!