Elixir:模式匹配结构的函数参数

Rud*_*koŭ 0 struct elixir pattern-matching

使用{:typed_struct, "~> 0.2.1"}库我有以下结构:

  defmodule RequestParams do
    use TypedStruct
    typedstruct do
      field :code, String.t()
      field :name, String.t()
    end
  end
Run Code Online (Sandbox Code Playgroud)

我正在尝试将函数参数模式匹配到结构:

def do_handle(params %RequestParams{}, _context) do
# instead of
# def do_handle(%{ "code" => code, "name" => name}, _context) do
Run Code Online (Sandbox Code Playgroud)

但我得到例外:

cannot find or invoke local params/2 inside match. Only macros can be
invoked in a match and they must be defined before their invocation.
Run Code Online (Sandbox Code Playgroud)

怎么了?是否有可能将函数参数与结构相匹配?

Ale*_*kin 6

问题原因

\n

中,函数调用中的括号不是强制性的(尽管是可取的)。也就是说,代码def foo(bar baz) do ...正在被解析和处理def foo(bar(baz)) do ...,因为解析器建议在函数调用中省略括号bar。您应该收到编译器发出的警告,准确说明这一点。应该阅读并消除警告。

\n

快速解决

\n

正如@peaceful-james 所指出的,括号内的模式匹配就可以了。

\n
def do_handle(%RequestParams{} = params, _context) do\n
Run Code Online (Sandbox Code Playgroud)\n

\xe2\x80\x9c而不是\xe2\x80\x9d

\n

你写了

\n
def do_handle(params %RequestParams{}, _context) do\n# instead of\n# def do_handle(%{ "code" => code, "name" => name}, _context) do\n
Run Code Online (Sandbox Code Playgroud)\n

即使语法正确,上面的代码也不等同于下面的代码。下面的代码将接受任何具有两个键"code"和 的映射"name",而上面的代码允许RequestParamsonly 的实例。还可以使下面的代码更加严格:

\n
def do_handle(%RequestParams{code: code, name: name}, _) do\n
Run Code Online (Sandbox Code Playgroud)\n

结构键

\n

但是atom中的结构除了作为键之外不能有任何东西。也就是说,如果您的初始代码被接受%{"code" => _}则无法在不修改调用代码的情况下将其转变为接受结构。

\n

打字的东西

\n

中的一等公民。我个人觉得合适。您应该从理解语言、OTP 原则、语言范式开始,然后才决定您是否想要和/或需要类型。

\n