Elixir中"|>"符号的用途是什么?

bri*_*tar 14 elixir

我搜索了Elixir和Phoenix文档,以及其他一些网站,比如Learn Elixir,没有运气.这是它的样子:

defp update_positions(item_ids) do
  item_ids = String.split(item_ids, ",")
                    |> Enum.map fn item_id -> String.to_integer(item_id) end

  items = Repo.all(Item |> where([item], item.id in array(^item_ids, :integer)))
  item_hash = Enum.reduce items, %{}, fn item, map -> Map.put(map, item.id, item) end

  item_ids
    |> Stream.with_index
    |> Enum.each fn {item_id, index} ->
      item = item_hash[item_id]
      Repo.update(%{item | position: index + 1})
    end
end
Run Code Online (Sandbox Code Playgroud)

起初我认为它只是一个行继续符号来保持代码可读,但Item |> where上面的行表示不然.它是列表理解还是指定输入类型的东西?

Chr*_*ord 27

我将从我的Elixir Express研讨会材料中复制:https: //github.com/chrismccord/elixir_express/blob/master/basics/06_pipeline_operator.md

管道运营商

Elixir中最简单但最有效的功能之一是管道操作员.管道运算符解决了许多函数式语言在编写一系列转换时所面临的问题,其中一个函数的输出需要作为输入传递给另一个函数.这需要反向读取解决方案以理解正在执行的操作,妨碍可读性并模糊代码的真实意图.酏剂优雅解决了这个问题通过允许函数的输出将被管道输送作为第一个参数到的另一个输入端.在编译时,功能层次结构将转换为嵌套的"后向"变体,否则将需要该变体.

iex(1)> "Hello" |> IO.puts
Hello
:ok
iex(2)> [3, 6, 9] |> Enum.map(fn x -> x * 2 end) |> Enum.at(2)
18
Run Code Online (Sandbox Code Playgroud)

要掌握管道提供的完整实用程序,请考虑从API获取新消息并将结果保存到数据库的模块.步骤顺序如下:

  • 按授权用户令牌查找帐户
  • 使用授权帐户从API获取新邮件
  • 将JSON响应转换为关键字消息列表
  • 将所有新消息保存到数据库

没有管道:

defmodule MessageService do
  ...
  def import_new_messages(user_token) do
    Enum.each(
      parse_json_to_message_list(
        fetch(find_user_by_token(user_token), "/messages/unread")
    ), &save_message(&1))
  end
  ...
end
Run Code Online (Sandbox Code Playgroud)

正确的命名和缩进有助于前一个块的可读性,但如果没有先花一点时间从内到外分解步骤来掌握对数据流的理解,其意图就不会立即显现出来.

现在考虑使用管道运算符的这一系列步骤:

使用Pipeline

defmodule MessageService do
  ...
  def import_new_messages(user_token) do
    user_token
    |> find_user_by_token
    |> fetch("/messages/unread")
    |> parse_json_to_message_list
    |> Enum.each(&save_message(&1))
  end
    ...
end
Run Code Online (Sandbox Code Playgroud)

将每个步骤的结果作为下一个允许的第一个参数进行管道允许程序被编写为一系列转换,任何读者都可以立即阅读和理解这些转换而无需花费额外的努力来解开函数,如第一个解决方案中那样.

Elixir标准库侧重于将函数的主题作为第一个参数,帮助和鼓励管道的自然使用.