【问题标题】:Elixir: pattern match function arguments to structElixir:结构的模式匹配函数参数
【发布时间】:2020-11-25 00:22:00
【问题描述】:

使用{: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.

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

【问题讨论】:

    标签: struct pattern-matching elixir


    【解决方案1】:

    你真的要写这个吗:

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

    【讨论】:

      【解决方案2】:

      问题原因

      中,函数调用中的括号不是强制性的(尽管是可取的。)也就是说,代码def foo(bar baz) do ... 正在被解析并被视为def foo(bar(baz)) do ...,因为解析器建议在调用函数@987654326 时省略括号@。你应该从编译器那里得到一个警告,就是这么说的。警告应该被阅读和消除。

      快速修复

      正如@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
      

      结构键

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

      打字的东西

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

      【讨论】:

        猜你喜欢
        • 2019-11-07
        • 2017-03-16
        • 2015-08-10
        • 1970-01-01
        • 1970-01-01
        • 2012-09-02
        • 1970-01-01
        • 1970-01-01
        • 2023-03-21
        相关资源
        最近更新 更多