【问题标题】:Use a tuple as arguments for a function in Elixir在 Elixir 中使用元组作为函数的参数
【发布时间】:2017-02-27 12:56:11
【问题描述】:

我正在用 Elixir 编写游戏引擎。 (是的,我知道这不是一种天生适合这种情况的语言——重点是看看非典型语言的使用如何影响结果的结构。)

因此,我要在游戏开始时运行几个监督者——但他们究竟应该监督什么取决于游戏。我的想法是让用户在config.exs 文件中列出必要的子项,以及参数和选项,作为元组列表,然后主管本身将简单地从应用程序环境中提取这些元组并将它们的内容用作worker\2(或worker\3,视情况而定)的参数。

但是,我找不到任何与 Python 的元组解包等效的 Elixir。对于这种特定情况,我可以通过一个简单的函数自己完成:

def unpack_worker({module, args}) do
  worker(module, args)
end

def unpack_worker({module, args, opts}) do
  worker(module, args, opts)
end

但这充其量感觉很笨拙,并且必须为我可能需要这种可配置性的每个功能重新编写。

【问题讨论】:

    标签: elixir argument-unpacking


    【解决方案1】:

    我相信您正在寻找Tuple.to_list/1apply/3

    使用这些,您可以根据元组的内容调用正确的arity函数:

    def unpack_worker(args) do
      apply(__MODULE__, :worker, Tuple.to_list(args))
    end
    

    如果您现在调用unpack_worker({}),它将调用worker()unpack_worker({:foo}) 将调用worker(:foo),依此类推。

    演示:

    defmodule A do
      def worker, do: IO.puts 0
      def worker(_), do: IO.puts 1
      def worker(_, _), do: IO.puts 2
      def worker(_, _, _), do: IO.puts 3
    
      def unpack_worker(tuple), do: apply(__MODULE__, :worker, Tuple.to_list(tuple))
    end
    
    A.unpack_worker({})
    A.unpack_worker({:a})
    A.unpack_worker({:a, :b})
    A.unpack_worker({:a, :b, :c})
    

    输出:

    0
    1
    2
    3
    

    【讨论】:

      【解决方案2】:

      我认为您需要知道元组的大小才能正确访问元素。也许对您的用例更好的数据结构是关键字列表,特别是考虑到它是您从配置中获得的?然后你可以解压worker:, args: 剩下的留作选项?

      【讨论】:

        【解决方案3】:

        我相信您会想要 elem/2tuple_size/1 函数的组合。

        iex(1)> a = {:foo, :bar, :baz}
        {:foo, :bar, :baz}
        iex(2)> tuple_size(a)
        3
        iex(3)> elem(a, 0)
        :foo
        iex(4)> elem(a, 5)
        ** (ArgumentError) argument error
            :erlang.element(6, {:foo, :bar, :baz})
        

        请注意,如果您在元组中不存在的索引处请求元素,您确实会收到参数错误。这意味着您仍然必须使用 if / case / cond / 多功能头或其他东西来区分您正在尝试做什么。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-08-16
          • 2019-10-23
          • 1970-01-01
          • 2018-12-02
          • 1970-01-01
          • 2014-04-29
          • 1970-01-01
          相关资源
          最近更新 更多