繁体   English   中英

Elixir运算符重载:使用宏定义专有范围

[英]Elixir Operator Overloading: Defining an exclusive range using Macros

为了更好地理解Elixir语言,我想尝试通过添加专用范围运算符...来进行运算符重载。 例如: 1...10将创建从1到但不包括10的范围。 (例如1...10 == 1..9

所以,我抬头的定义.. ,因为功能...当然会非常相似。

然后,Mmy模块变为:

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中定义的infix运算符数量有限:

\\, <-, |, ~>>, <<~, ~>, <~, <~>, <|>, <<<, >>>, |||, &&&, and ^^^

它们是在解析器中预定义的,但未实现(或至少默认情况下未导入)。 这使它们可用于自定义实现,但是除非修改和重新编译Elixir本身,否则您无法创建自己的添加到此列表。

...不是其中之一,因此将无法使用。

从评论:

||| &&&^^^<<<>>>~~~默认情况下不会导入,但是它们是默认Elixir标准库的Bitwise模块的一部分。

有关更多详细信息,请参见http://www.rodneyfolz.com/custom-infix-functions-in-elixir/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM