【问题标题】:Using the cons operator "|" with Keyword lists使用 cons 运算符“|”带有关键字列表
【发布时间】:2021-03-30 20:24:44
【问题描述】:

我正在尝试定义一个函数,我在其中指定部分关键字列表,然后将剩余的 opts 匹配为尾部。

def my_func(foo: 22, bar: 42 | baz) do
  IO.inspect(baz)
end

my_func(foo: 22, bar: 42, another_arg: 11, even_more_args: 12)

这个想法是让baz 成为一个包含 [another_arg: 11, even_more_args: 12] 的关键字列表

这不会编译,失败并出现以下错误:

错位运算符 |/2

该 |运算符通常在括号之间用作 cons 运算符:

[头|尾]

但是,我可以使用以下方式对关键字列表进行模式匹配:

def my_func([{:foo, 22}, {:bar, 42} | baz]) do
end

由于关键字是元组列表的语义糖,我不清楚为什么后一种语法有效,而前者无效。我是否缺少一些语法才能将| 与关键字一起使用?

【问题讨论】:

  • 也许最好的答案是使用 Map %{},因为它在函数签名上具有更好的语义 w.r.t 部分匹配,但希望听到关键字列表是否存在任何选项。
  • 列表保持顺序,而地图不保持,如果你不关心项目的顺序,你应该使用地图。

标签: elixir


【解决方案1】:

发生这种情况是因为关键字列表语法在列表上下文中有效,这意味着此类语法无效:

iex> test = foo: 22
** (SyntaxError) iex:8:8: syntax error before: foo

但这是有效的:

iex> test = [foo: 22]
[foo: 22]
def my_func([[foo: 22], [bar: 42] | baz]) do
end

当然前面的语法是不合适的,因为它会生成嵌套列表,但是你不能在没有列表的情况下使用关键字,所以你必须明确地将它写成一个元组。

我建议使用++/2 运算符:

def my_func([foo: 22, bar: 42] ++ rest) do
  IO.inspect(rest)
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-20
    • 2012-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多