You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用元编程创建支持结构体模式匹配的Elixir函数?

在Elixir中用元编程实现带结构体模式匹配的Getter函数

你当前的非模式匹配实现

defmodule Board do
  defstruct [:red_pieces, :black_pieces]

  def red_pieces(board), do: board.red_pieces
  def black_pieces(board), do: board.black_pieces
end

用元编程生成带模式匹配的Getter函数

通过编译时代码生成,可以自动为指定字段创建带结构体模式匹配的函数:

defmodule Board do
  defstruct [:red_pieces, :black_pieces]

  # 遍历目标字段,编译时生成对应函数
  for field <- [:red_pieces, :black_pieces] do
    def unquote(field)(%__MODULE__{unquote(field) => value}), do: value
  end
end

代码说明

  • for循环在模块编译阶段执行,遍历你指定的字段列表
  • unquote/1将编译时变量field注入到函数名和结构体匹配模式中,最终生成的代码和手动编写如下代码完全一致:
    def red_pieces(%Board{red_pieces: value}), do: value
    def black_pieces(%Board{black_pieces: value}), do: value
    
  • 调用时直接匹配结构体字段,避免了函数体内的字段访问,更贴合Elixir的模式匹配风格

可选:添加非结构体参数的兜底处理

如果需要处理传入非%Board{}的情况,可以在循环中添加兜底子句:

for field <- [:red_pieces, :black_pieces] do
  def unquote(field)(%__MODULE__{unquote(field) => value}), do: value
  # 根据需求返回nil或抛出错误
  def unquote(field)(_invalid_board), do: raise("Invalid Board struct")
end

测试验证

board = %Board{red_pieces: [:r1, :r2], black_pieces: [:b1, :b2]}
Board.red_pieces(board) # => [:r1, :r2]
Board.black_pieces(board) # => [:b1, :b2]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 10:28:10