You need to enable JavaScript to run this app. Elixir 中如何使用管道语法重构代码并访问中间结果?
优惠活动
大模型
产品
解决方案
定价
更多

Elixir 中如何使用管道语法重构代码并访问中间结果?

Elixir管道语法优化实现

Elixir管道|>的核心运作规则非常明确:将上一个表达式的输出结果,自动作为下一个被调用函数的第一个位置参数传入。多数人管道语法写不通,本质是没遵守这个传参规则,或是把存在多依赖的计算硬拆成割裂的链式调用。

优化后的可运行代码

def show(conn, %{"id" => id}) do
  project =
    id
    |> Clients.get_project!()
    |> then(fn proj ->
      total_budget = total_budget(proj.budget_items)
      used_budget = budget_used(proj.work_items)
      %{proj |
        budget: total_budget,
        budget_used: used_budget,
        budget_remaining: total_budget - used_budget
      }
    end)

  changeset =
    %BudgetItem{project_id: project.id}
    |> Clients.change_budget_item()

  render(conn, "show.html", project: project, changeset: changeset)
end

写法说明

  • 没有沿用原本三次独立Map.put_new的拆分逻辑,而是在单个then/2块中,一次性接住上游传入的初始project结构,集中完成三个关联值的计算,一次性更新struct字段,减少重复的结构取值操作。因为示例中补充的budget、budget_used、budget_remaining都是计算出来的虚拟字段,原本不存在于Project struct中,因此使用struct语法更新和原本的Map.put_new行为完全一致,不存在覆盖已有字段的问题。
  • then/2是适配管道的灵活工具:它可以完整接住上游的传值,不受管道自动插第一参数的规则限制,适合处理存在多字段依赖的计算场景。
  • 若使用Elixir 1.15及以上版本,可通过桩语法简化逐字段补充的写法,和原本的代码逻辑完全对齐:
    project =
      id
      |> Clients.get_project!()
      |> Map.put_new(:budget, total_budget(.budget_items))
      |> Map.put_new(:budget_used, budget_used(.work_items))
      |> Map.put_new(:budget_remaining, .budget - .budget_used)
    

常见踩坑点

  • 不要把多依赖的计算硬拆成无关联的链式步骤:比如直接把.budget - .budget_used作为独立管道步骤传参,此时管道中的project还未注入刚计算的budget、budget_used字段,会拿到nil导致计算错误。
  • 不要手动错误排列函数参数:比如写Map.put_new(:budget, value, project),管道会自动把上游的project插到第一个参数位置,实际执行会变成Map.put_new(project, :budget, value),额外手动传参会直接触发函数匹配错误。

内容的提问来源于stack exchange,提问作者tomr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.10 14:15:01