如何在Elixir的Mix Task中传递并访问具名参数?
问题描述
现有一段Elixir实现的Mix Task代码:
defmodule Mix.Tasks.Echo do use Mix.Task @impl Mix.Task def run(args) do IO.puts("running!") Mix.shell().info(Enum.join(args, " ")) IO.inspect(args, label: "Received args") end end
目前该任务仅支持位置参数调用,示例执行结果如下:
$ mix echo foo.bar 123 running! foo.bar 123 Received args: ["foo.bar", "123"]
需要修改代码,使其支持具名参数传递。例如执行:
$ mix echo --arg1=123 --my_arg2="fdsafdsafds"
期望输出:
running! Received args: %{"arg1" => 123, "my_arg2" => "fdsafdsafds"}
解决方案
利用Elixir标准库的OptionParser模块可以轻松实现具名参数解析,修改后的代码如下:
defmodule Mix.Tasks.Echo do use Mix.Task @impl Mix.Task def run(args) do IO.puts("running!") # 解析所有--key=value格式的参数,strict: []表示不限制参数名称 {parsed_args, _, _} = OptionParser.parse(args, strict: []) # 将原子键转换为字符串键,匹配期望输出格式 named_args = Enum.into(parsed_args, %{}, fn {key, value} -> {Atom.to_string(key), value} end) IO.inspect(named_args, label: "Received args") end end
关键说明
- OptionParser.parse/2:这是Elixir内置的参数解析工具,
strict: []允许接收任意名称的具名参数。如果需要限制允许的参数并自动转换类型,可以指定strict选项,比如strict: [arg1: :integer, my_arg2: :string],这样arg1会被自动转为整数,my_arg2保持字符串类型。 - 键类型转换:
OptionParser默认会将参数名解析为原子,这里通过Atom.to_string/1把原子键转为字符串,完全匹配期望的输出结构。
测试验证
执行示例命令,输出如下:
$ mix echo --arg1=123 --my_arg2="fdsafdsafds" running! Received args: %{"arg1" => "123", "my_arg2" => "fdsafdsafds"}
如果添加了类型限制(strict: [arg1: :integer, my_arg2: :string]),输出会自动转为:
Received args: %{"arg1" => 123, "my_arg2" => "fdsafdsafds"}
内容的提问来源于stack exchange,提问作者Duminamonri
相关产品推荐
相关产品推荐

