Elixir:模式匹配函数参数到结构
Elixir: pattern match function arguments to struct
使用 {:typed_struct, "~> 0.2.1"} 库我有以下结构:
defmodule RequestParams do
use TypedStruct
typedstruct do
field :code, String.t()
field :name, String.t()
end
end
我正在尝试将函数参数模式匹配到结构:
def do_handle(params %RequestParams{}, _context) do
# instead of
# def do_handle(%{ "code" => code, "name" => name}, _context) do
但我遇到异常:
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.
怎么了?是否有可能将函数参数与结构匹配?
你真的想写这个吗:
def do_handle(%RequestParams{}=params, _context) do
问题原因
在 elixir 中,函数调用中的括号不是强制性的(尽管是可取的。)也就是说,代码 def foo(bar baz) do ...
被解析并被视为 def foo(bar(baz)) do ...
因为解析器建议省略调用函数 bar
时的括号。你应该从编译器那里得到一个 warning,准确地说。应该阅读并删除警告。
快速修复
正如@peaceful-james指出的那样,括号内的模式匹配就可以了。
def do_handle(%RequestParams{} = params, _context) do
“而不是”
你写了
def do_handle(params %RequestParams{}, _context) do
# instead of
# def do_handle(%{ "code" => code, "name" => name}, _context) do
即使语法正确,上面的代码也不等同于下面的代码。下面的代码将接受任何映射,有两个键 "code"
和 "name"
,而上面的代码只允许 RequestParams
的实例。还可以使下面的代码更严格:
def do_handle(%RequestParams{code: code, name: name}, _) do
结构键
但是 elixir 中的结构只能将 atom
作为键。也就是说,如果您的初始代码接受了 %{"code" => _}
,则无法在不修改调用代码的情况下将其变成接受结构。
输入内容
类型不是 elixir 中的 first-class 公民。我个人觉得很合适。您应该从了解语言、OTP 原则、语言范式开始 ,然后才 决定您是否想要 and/or 需要类型。
使用 {:typed_struct, "~> 0.2.1"} 库我有以下结构:
defmodule RequestParams do
use TypedStruct
typedstruct do
field :code, String.t()
field :name, String.t()
end
end
我正在尝试将函数参数模式匹配到结构:
def do_handle(params %RequestParams{}, _context) do
# instead of
# def do_handle(%{ "code" => code, "name" => name}, _context) do
但我遇到异常:
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.
怎么了?是否有可能将函数参数与结构匹配?
你真的想写这个吗:
def do_handle(%RequestParams{}=params, _context) do
问题原因
在 elixir 中,函数调用中的括号不是强制性的(尽管是可取的。)也就是说,代码 def foo(bar baz) do ...
被解析并被视为 def foo(bar(baz)) do ...
因为解析器建议省略调用函数 bar
时的括号。你应该从编译器那里得到一个 warning,准确地说。应该阅读并删除警告。
快速修复
正如@peaceful-james指出的那样,括号内的模式匹配就可以了。
def do_handle(%RequestParams{} = params, _context) do
“而不是”
你写了
def do_handle(params %RequestParams{}, _context) do
# instead of
# def do_handle(%{ "code" => code, "name" => name}, _context) do
即使语法正确,上面的代码也不等同于下面的代码。下面的代码将接受任何映射,有两个键 "code"
和 "name"
,而上面的代码只允许 RequestParams
的实例。还可以使下面的代码更严格:
def do_handle(%RequestParams{code: code, name: name}, _) do
结构键
但是 elixir 中的结构只能将 atom
作为键。也就是说,如果您的初始代码接受了 %{"code" => _}
,则无法在不修改调用代码的情况下将其变成接受结构。
输入内容
类型不是 elixir 中的 first-class 公民。我个人觉得很合适。您应该从了解语言、OTP 原则、语言范式开始 ,然后才 决定您是否想要 and/or 需要类型。