gpt4 book ai didi

elixir - 管道图正在尝试调用原始函数

转载 作者:行者123 更新时间:2023-12-01 11:39:42 24 4
gpt4 key购买 nike

下面的代码应该读取一个文件并创建一个 Item记录每一行:

defmodule Ship do
defrecord Item, product_code: 0, quantity: 0, destination: ""

def load_data do
File.read!("data")
|> String.split
|> Enum.map &(String.split &1, ",")
|> Enum.map &(list_to_item &1)
end

defp list_to_item([pc, q, d | []]) do
{parsed_q, _} = Integer.parse q
Item.new product_code: pc, quantity: parsed_q, destination: d
end
end

有一个data包含以下内容的文件:

1,100,London
1,30,Lisbon
3,2,Braga

问题是,当我执行 load_data 函数时,看起来对 Enum.map 的最后一次调用试图递归调用父函数 (load_data),并抛出 BadArityError .

输出如下:

iex(1)> Ship.load_data
** (BadArityError) #Function<0.127338698/1 in Ship.load_data/0> with arity 1 called with 2 arguments ({:cont, []}, #Function<30.103209896/2 in Enum.map/2>)
(elixir) lib/enum.ex:2000: Enumerable.Function.reduce/3
(elixir) lib/enum.ex:879: Enum.map/2
ship.ex:8: Ship.load_data/0

有趣的是,如果我改变 load_data功能:

def load_data do
list = File.read!("data")
|> String.split
|> Enum.map &(String.split &1, ",")

Enum.map list, &(list_to_item &1)
end

它按预期工作:

iex(2)> Ship.load_data
[Ship.Item[product_code: "1", quantity: 100, destination: "London"],
Ship.Item[product_code: "1", quantity: 30, destination: "Lisbon"],
Ship.Item[product_code: "3", quantity: 2, destination: "Braga"]]

那么,您知道第一个版本中的错误来自哪里吗?他们不应该是等价的吗?

顺便说一句,我正在使用 Elixir 0.12.4。

最佳答案

您的代码实际上等同于此:

File.read!("data") 
|> String.split
|> Enum.map (&(String.split &1, ",") |> Enum.map &(list_to_item &1))

你需要更多的括号,因为|>比无括号的函数应用有更高的优先级:

File.read!("data") 
|> String.split
|> Enum.map(&(String.split &1, ","))
|> Enum.map(&(list_to_item &1))

这是 Elixir 设计中的一个不幸缺陷(也是我仍然喜欢 Erlang 的唯一原因)。

关于elixir - 管道图正在尝试调用原始函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22591141/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com