我正在尝试在模块内创建两个函数
:red_pieces
和:black_pieces
,旨在从结构中获取元素。我希望编译后的函数在 Board
上进行模式匹配,以参数
%Board
为例。所以这看起来像:%Board{red_pieces: pieces}
目前我可以让它在没有模式匹配的情况下工作,只需获取函数体中的结构字段,如下所示:
def red_pieces(%Board{red_pieces: pieces}, n)
case pieces do
%{^n => b} -> {:ok, b}
_ -> {:nil, :nil}
end
end
但是,我不想先执行
defmodule Board do
defstruct black_pieces: %{}, red_pieces: %{}
# Creates functions: &Board.red_pieces/2 and &Board.black_pieces/2
for fg <- [:red_pieces, :black_pieces] do
def unquote(fg)(board = %__MODULE__{}, n) do
case board.unquote(fg) do
%{^n => b} -> {:ok, b}
_ -> {:nil, :nil}
end
end
end
end
然后执行
b = %__MODULE__{}
我想对 case b.unquote(fg)
的值进行模式匹配,这样它就像 fg
,但我不知道如何做到这一点。显然,我可以明确地创建两个单独的函数,但出于一般学习目的,我想知道是否可以使用元编程。
%__MODULE{red_pieces: pieces}
,例如
unquote
:%__MODULE__{unquote(fg) => pieces}
for fg <- [:red_pieces, :black_pieces] do
def unquote(fg)(%__MODULE__{unquote(fg) => pieces}, n) do
case pieces do
%{^n => b} -> {:ok, b}
_ -> {nil, nil}
end
end
end
只是
%{black_pieces: pieces}
的语法糖。您需要对其进行脱糖才能使用 %{:black_pieces => pieces}
,否则它将不是有效的 Elixir 语法。