传递 :discard 到 Enum.chunk_every 时出现 FunctionClauseError

问题描述 投票:0回答:1

所以我一直在做 udemy 课程来学习 Elixir,我应该在其中获取列表并创建包含长度为 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)
elixir
1个回答
0
投票

你正在这样做:

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)
    ,其中
    count
    也作为第三个参数
    step
    传递。
  2. 三参数形式:
    Enum.chunk_every/4
    ,实际上是四参数形式,其中第四个参数
    leftover
    的默认值是空列表:
    chunk_every(list, count, step)
    chunk_every(list, count, step, [])
    。这与两个参数的形式不同,因为
    step
    不是可选的。
  3. 四参数形式,与三参数形式相同,但具有明确的
    leftover
    值。

您的代码正在执行

Enum.chunk_every(enum, 3, :discard)
,尝试将
:discard
作为第四个
leftover
参数传递,但不传递所需的第三个
step
参数。所以 Elixir 正确地抱怨这个函数没有接受
(list, integer, atom)
参数的版本。修复方法是传递所需的第三个参数
step
,其值与
count
相同。

这很令人困惑,因为双参数版本允许

step
自动默认为
count
,但四参数版本要求您显式传递它。

© www.soinside.com 2019 - 2024. All rights reserved.