Elixir 运算符重载:使用宏定义独占范围
Elixir Operator Overloading: Defining an exclusive range using Macros
为了更好地理解 Elixir 语言,我想通过添加排他范围运算符 ...
来尝试进行运算符重载。一个例子: 1...10
然后会创建一个从 1 到但不包括 10 的范围。 (例如 1...10 == 1..9
)
所以,我查找了 the definition of ..
,因为 ...
的功能当然非常相似。
我的模块就变成了:
defmodule Sequences.Ranges do
defmacro first ... last do
case is_float(first) or is_float(last) or
is_atom(first) or is_atom(last) or
is_binary(first) or is_binary(last) or
is_list(first) or is_list(last) do
true ->
raise ArgumentError,
"ranges (first...last) expect both sides to be integers, " <>
"got: #{Macro.to_string({:"Sequences.Ranges...", [], [first, last]})}"
false ->
case __CALLER__.context do
nil -> quote do: Elixir.Range.new(unquote(first), unquote(last-1))
_ -> {:%{}, [], [__struct__: Elixir.Range, first: first, last: (last-1)]}
end
end
end
end
但是,在编译该模块时,出现以下错误:
== Compilation error on file lib/sequences/ranges.ex ==
** (CompileError) lib/sequences/ranges.ex:6: cannot invoke local .../1 inside match
(stdlib) lists.erl:1353: :lists.mapfoldl/3
我做错了什么?
您可以在 Elixir 中定义的中缀运算符数量有限:
\, <-, |, ~>>, <<~, ~>, <~, <~>, <|>, <<<, >>>, |||, &&&, and ^^^
它们是在解析器中预定义的,但未实现(或者至少默认情况下未导入)。这使它们可用于自定义实现,但您不能创建自己的实现以添加到此列表,除非您修改并重新编译 Elixir 本身。
...
不是其中之一,所以它不会起作用。
来自评论:
|||
, &&&
, ^^^
, <<<
, >>>
and ~~~
are not by default imported, but are part of the default Elixir standard library's Bitwise
module.
有关详细信息,请参阅 http://www.rodneyfolz.com/custom-infix-functions-in-elixir/。
为了更好地理解 Elixir 语言,我想通过添加排他范围运算符 ...
来尝试进行运算符重载。一个例子: 1...10
然后会创建一个从 1 到但不包括 10 的范围。 (例如 1...10 == 1..9
)
所以,我查找了 the definition of ..
,因为 ...
的功能当然非常相似。
我的模块就变成了:
defmodule Sequences.Ranges do
defmacro first ... last do
case is_float(first) or is_float(last) or
is_atom(first) or is_atom(last) or
is_binary(first) or is_binary(last) or
is_list(first) or is_list(last) do
true ->
raise ArgumentError,
"ranges (first...last) expect both sides to be integers, " <>
"got: #{Macro.to_string({:"Sequences.Ranges...", [], [first, last]})}"
false ->
case __CALLER__.context do
nil -> quote do: Elixir.Range.new(unquote(first), unquote(last-1))
_ -> {:%{}, [], [__struct__: Elixir.Range, first: first, last: (last-1)]}
end
end
end
end
但是,在编译该模块时,出现以下错误:
== Compilation error on file lib/sequences/ranges.ex ==
** (CompileError) lib/sequences/ranges.ex:6: cannot invoke local .../1 inside match
(stdlib) lists.erl:1353: :lists.mapfoldl/3
我做错了什么?
您可以在 Elixir 中定义的中缀运算符数量有限:
\, <-, |, ~>>, <<~, ~>, <~, <~>, <|>, <<<, >>>, |||, &&&, and ^^^
它们是在解析器中预定义的,但未实现(或者至少默认情况下未导入)。这使它们可用于自定义实现,但您不能创建自己的实现以添加到此列表,除非您修改并重新编译 Elixir 本身。
...
不是其中之一,所以它不会起作用。
来自评论:
|||
,&&&
,^^^
,<<<
,>>>
and~~~
are not by default imported, but are part of the default Elixir standard library'sBitwise
module.
有关详细信息,请参阅 http://www.rodneyfolz.com/custom-infix-functions-in-elixir/。