當前位置: 首頁>>編程示例 >>用法及示例精選 >>正文


Elixir OptionParser.parse用法及代碼示例

Elixir語言中 OptionParser.parse 相關用法介紹如下。

用法:

parse(argv, opts \\ [])
@spec parse(argv(), options()) :: {parsed(), argv(), errors()}

argv 解析為關鍵字列表。

它返回一個 three-element 元組,其形式為 {parsed, args, invalid} ,其中:

  • parsed 是已解析開關的關鍵字列表,其中包含 {switch_name, value} 元組; switch_name 是表示開關名稱的原子,而 value 是根據 opts 解析的該開關的值(有關更多信息,請參見 "Examples" 部分)
  • argsargv 中剩餘參數的列表作為字符串
  • invalid 是作為 {option_name, value} 的無效選項列表,其中 option_name 是原始選項,如果選項不是預期的,則 valuenil,如果值不具有預期類型,則為字符串值對於相應的選項

Elixir 將開關轉換為帶下劃線的原子,因此 --source-path 變為 :source_path 。這樣做是為了更好地適應 Elixir 約定。但是,這意味著開關不能包含下劃線,並且包含下劃線的開關總是會在無效開關列表中返回。

解析時,通常會列出開關及其預期類型:

iex> OptionParser.parse(["--debug"], strict: [debug: :boolean])
{[debug: true], [], []}

iex> OptionParser.parse(["--source", "lib"], strict: [source: :string])
{[source: "lib"], [], []}

iex> OptionParser.parse(
...>   ["--source-path", "lib", "test/enum_test.exs", "--verbose"],
...>   strict: [source_path: :string, verbose: :boolean]
...> )
{[source_path: "lib", verbose: true], ["test/enum_test.exs"], []}

我們將在下麵探索選項解析器的有效開關和操作模式。

選項

支持以下選項:

  • :switches:strict - 請參閱下麵的 "Switch definitions" 部分
  • :allow_nonexistent_atoms - 請參閱下麵的“解析未知開關”部分
  • :aliases - 請參閱下麵的 "Aliases" 部分

開關定義

可以通過以下兩個選項之一指定開關:

  • :strict - 定義嚴格開關及其類型。 argv 中未在列表中指定的任何開關都將在無效選項列表中返回。這是解析選項的首選方式。

  • :switches - 定義開關及其類型。此函數仍會嘗試解析不在此列表中的開關。

這兩個選項都接受一個關鍵字列表,其中鍵是定義開關名稱的原子,值是開關的type(有關更多信息,請參見下麵的"Types" 部分)。

請注意,您應該隻提供:switches:strict 選項。如果兩者都提供,則會引發 ArgumentError 異常。

類型

OptionParser 解析的開關可以采用零個或一個參數。

以下開關類型不帶參數:

  • :boolean - 在給定時將值設置為 true(另請參見下麵的 "Negation switches" 部分)
  • :count - 計算給定開關的次數

以下開關采用一個參數:

  • :integer - 將值解析為整數
  • :float - 將值解析為浮點數
  • :string - 將值解析為字符串

如果無法根據給定類型解析開關,則在無效選項列表中返回。

修飾符

可以使用修飾符指定開關,這會改變它們的行為方式。支持以下修飾符:

  • :keep - 保留重複的元素而不是覆蓋它們;適用於除 :count 之外的所有類型。指定 switch_name: :keep 假定 :switch_name 的類型將為 :string

要將 :keep:string 以外的類型一起使用,請使用列表作為開關的類型。例如:[foo: [:integer, :keep]]

否定開關

如果開關 SWITCH 被指定為具有類型 :boolean ,它也可以作為 --no-SWITCH 傳遞,這會將選項設置為 false

iex> OptionParser.parse(["--no-op", "path/to/file"], switches: [op: :boolean])
{[op: false], ["path/to/file"], []}

解析未知開關

當給出:switches 選項時, OptionParser 將嘗試解析未知開關:

iex> OptionParser.parse(["--debug"], switches: [key: :string])
{[debug: true], [], []}

即使我們沒有在開關列表中指定--debug,它也是返回選項的一部分。這也可以:

iex> OptionParser.parse(["--debug", "value"], switches: [key: :string])
{[debug: "value"], [], []}

後跟一個值的開關將被分配該值,作為一個字符串。沒有參數的開關將自動設置為 true 。由於我們無法斷言開關值的類型,因此最好使用 :strict 選項,它隻接受已知開關並始終驗證它們的類型。

如果您確實想解析未知開關,請記住 Elixir 將開關轉換為原子。由於原子不是garbage-collected,OptionParser 將僅解析轉換為運行時使用的原子的開關以避免泄漏原子。例如,下麵的代碼將丟棄 --option-parser-example 開關,因為 :option_parser_example 原子從未在任何地方使用:

OptionParser.parse(["--option-parser-example"], switches: [debug: :boolean])
# The :option_parser_example atom is not used anywhere below

但是,隻要稍後(或更早)在同一模塊中的某個時間點使用 :option_parser_example atom,下麵的代碼就可以工作。例如:

{opts, _, _} = OptionParser.parse(["--option-parser-example"], switches: [debug: :boolean])
# ... then somewhere in the same module you access it ...
opts[:option_parser_example]

換句話說,Elixir 隻會解析運行時使用的選項,而忽略所有其他選項。如果您想解析所有開關,無論它們是否存在,您可以通過傳遞allow_nonexistent_atoms: true 作為選項來強製創建原子。請謹慎使用此選項。它僅在您構建接收dynamically-named 參數的命令行 應用程序時有用,並且必須在long-running 係統中避免使用。

別名

可以在 :aliases 選項中指定一組別名:

iex> OptionParser.parse(["-d"], aliases: [d: :debug], strict: [debug: :boolean])
{[debug: true], [], []}

例子

以下是使用不同類型和修飾符的一些示例:

iex> OptionParser.parse(["--unlock", "path/to/file"], strict: [unlock: :boolean])
{[unlock: true], ["path/to/file"], []}

iex> OptionParser.parse(
...>   ["--unlock", "--limit", "0", "path/to/file"],
...>   strict: [unlock: :boolean, limit: :integer]
...> )
{[unlock: true, limit: 0], ["path/to/file"], []}

iex> OptionParser.parse(["--limit", "3"], strict: [limit: :integer])
{[limit: 3], [], []}

iex> OptionParser.parse(["--limit", "xyz"], strict: [limit: :integer])
{[], [], [{"--limit", "xyz"}]}

iex> OptionParser.parse(["--verbose"], switches: [verbose: :count])
{[verbose: 1], [], []}

iex> OptionParser.parse(["-v", "-v"], aliases: [v: :verbose], strict: [verbose: :count])
{[verbose: 2], [], []}

iex> OptionParser.parse(["--unknown", "xyz"], strict: [])
{[], ["xyz"], [{"--unknown", nil}]}

iex> OptionParser.parse(
...>   ["--limit", "3", "--unknown", "xyz"],
...>   switches: [limit: :integer]
...> )
{[limit: 3, unknown: "xyz"], [], []}

iex> OptionParser.parse(
...>   ["--unlock", "path/to/file", "--unlock", "path/to/another/file"],
...>   strict: [unlock: :keep]
...> )
{[unlock: "path/to/file", unlock: "path/to/another/file"], [], []}

相關用法


注:本文由純淨天空篩選整理自elixir-lang.org大神的英文原創作品 OptionParser.parse(argv, opts \\ [])。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。