首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Elixir映射中相同值键名称的模式匹配快捷方式

Elixir映射中相同值键名称的模式匹配快捷方式
EN

Stack Overflow用户
提问于 2017-06-01 14:02:48
回答 2查看 634关注 0票数 5

我在这种风格中做了相当多的模式匹配:

代码语言:javascript
复制
def action(%{start_date: start_date, amount: amount, notify: notify %}) do
  # some action
end

大多数情况下,我为参数选择的名称在映射中是相同的。有没有一种快捷方式可以指定模式匹配大小写,而不会重复键和值的相同名称?

下面这段伪代码中的内容如下:

代码语言:javascript
复制
def action(%{start_date: %s, amount: %s, notify: %s}) do
  IO.inspect(start_date)
  # some action
end
EN

回答 2

Stack Overflow用户

发布于 2017-06-01 14:38:39

AFAIK,没有什么是开箱即用的,但人们可以简单地为自己创建一个宏来服务于此目的:

代码语言:javascript
复制
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

上面的代码当然只是一个MCVE,你可能需要以某种方式增强它,以更优雅地处理边角情况(并且,很可能,拥有更明确的可读宏,它的行为比仅仅是输出AST更智能,并考虑到绑定等),但我相信这解释了这个想法。

票数 2
EN

Stack Overflow用户

发布于 2017-06-02 13:29:23

我引入了一个符号~m{...}来实现析构任务。

代码语言:javascript
复制
~m{foo bar} = %{foo: 1, bar: 2}
foo  #=> 1
bar  #=> 2

下面是我如何实现sigil

代码语言:javascript
复制
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

使用

代码语言:javascript
复制
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
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44299600

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档