如何使用元编程创建具有结构模式匹配的函数?

问题描述 投票:0回答:1

我正在尝试在模块内创建两个函数

: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
,但我不知道如何做到这一点。
显然,我可以明确地创建两个单独的函数,但出于一般学习目的,我想知道是否可以使用元编程。

elixir metaprogramming
1个回答
0
投票
%__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 语法。
    

© www.soinside.com 2019 - 2024. All rights reserved.