我在这种风格中做了相当多的模式匹配:
def action(%{start_date: start_date, amount: amount, notify: notify %}) do
# some action
end
大多数情况下,我为参数选择的名称与地图中的名称相同。是否有指定模式匹配大小写的快捷方式,而不重复键和值的相同名称?
这段伪代码中的内容:
def action(%{start_date: %s, amount: %s, notify: %s}) do
IO.inspect(start_date)
# some action
end
答案 0 :(得分:2)
AFAIK, there is nothing out of the box, but one could simply create a macro for themselves to serve that purpose:
defmodule M do
defmacro struct(params) do
{:%{}, [], Enum.map(params, fn e -> {e, {e, [], Elixir}} end)}
end
end
defmodule Test do
require M # to use macro
def action(M.struct([:a, :b]) = params),
do: IO.inspect params, label: "Params are"
end
Test.action(%{a: 42, b: :ok})
#⇒ Params are: %{a: 42, b: :ok}
Test.action(%{a: 42})
** (FunctionClauseError) no function clause matching in Test.action/1
The code above is of course just an MCVE, you probably need to enhance it somehow to handle corner cases more gracefully (and, probably, to have the more explicit readable macro that behaves smarter than just spitting the AST out, and considers the binding, etc,) but I believe that explains the idea.
答案 1 :(得分:1)
我引入了一个sigil ~m{...}
来实现破坏性任务。
~m{foo bar} = %{foo: 1, bar: 2}
foo #=> 1
bar #=> 2
以下是我实施sigil的方法
defmodule DestructingAssignment do
defmacro __using__(_) do
quote do: import unquote(__MODULE__)
end
defmacro sigil_m({:<<>>, _line, [string]}, []) do
spec = string
|> String.split
|> Stream.map(&String.to_atom/1)
|> Enum.map(&{&1, {&1, [], nil}})
{:%{}, [], spec}
end
end
<强>用法强>
defmodule Foo do
use DestructingAssignment
def foo(~m{bar}) do
# Do whatever you want with bar
IO.inspect(bar)
end
end
Foo.foo(%{bar: 1, baz: 2})
1