简体   繁体   English

Elixir:模式匹配 function arguments 到结构

[英]Elixir: pattern match function arguments to struct

Using {:typed_struct, "~> 0.2.1"} library I have following struct:使用{:typed_struct, "~> 0.2.1"}库我有以下结构:

  defmodule RequestParams do
    use TypedStruct
    typedstruct do
      field :code, String.t()
      field :name, String.t()
    end
  end

I am trying to pattern match function parameters to struct:我正在尝试将 function 参数模式匹配到结构:

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

But I get exception:但我得到例外:

 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.

What is wrong?怎么了? And is it possible at all to match function parameters to struct?是否有可能将 function 参数与结构相匹配?

Cause of the issue问题的原因

In , parentheses in function calls are not mandatory (although desirable.) That said, the code def foo(bar baz) do... is being parsed and treated as def foo(bar(baz)) do... because the parser suggests omitted parentheses in call to the function bar .中,function 调用中的括号不是强制性的(尽管是可取的。)也就是说,代码def foo(bar baz) do...被解析并视为def foo(bar(baz)) do...因为parser 建议在调用 function bar时省略括号。 You should have got a warning from the compiler, saying exactly that.你应该从编译器那里得到一个警告,确切地说。 Warnings are supposed to be read and eliminated.警告应该被阅读和消除。

Quick fix快速解决

As it is pointed out by @peaceful-james, pattern matching inside parentheses would do.正如@peaceful-james 所指出的那样,括号内的模式匹配就可以了。

def do_handle(%RequestParams{} = params, _context) do

“Instead of” “代替”

You wrote你写了

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

Even if it was syntactically correct, the code above is not equivalent to the code below.即使语法正确,上面的代码也不等同于下面的代码。 The code below would accept any map, having two keys "code" and "name" , while the code above allows instances of RequestParams only.下面的代码将接受任何 map,有两个键"code""name" ,而上面的代码只允许RequestParams的实例。 One might also make the code below more strict with:也可以使下面的代码更严格:

def do_handle(%RequestParams{code: code, name: name}, _) do

Struct keys结构键

But structs in cannot have anything but atom as a key.但是中的结构除了atom作为键之外不能有任何东西。 That said, if your initial code accepted %{"code" => _} there is no way to turn it into accepting a struct without modifying the calling code.也就是说,如果您的初始代码接受%{"code" => _} ,则无法在不修改调用代码的情况下将其转变为接受结构。

Typed stuff打字的东西

Types are not the first-class citizens in .类型不是中的一等公民。 I personally find it appropriate.我个人觉得合适。 You should start with understanding the language, OTP principles, the paradigm of the language and only after that decide whether you want and/or need types at all.您应该从了解语言、OTP 原则、语言范式开始,然后再决定是否需要和/或需要类型。

Do you actually mean to write this:你真的是想写这个:

def do_handle(%RequestParams{}=params, _context) do

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM