【问题标题】:How to use bitwise operators in an elixir when guard clause?保护子句时如何在长生不老药中使用按位运算符?
【发布时间】:2017-06-08 23:08:52
【问题描述】:

我有以下函数,它只需要与 n 的值匹配,它是 2 个整数的幂 (1, 2, 4, 8, 16, 32, 64, ...):

defmodule MyModule do
  def my_func(n) when is_power_of_two(n) do
     ## Some expression
  end
  def is_power_of_two(x) do
    (x != 0)
        and (x &&& (x - 1)) == 0)
  end
end

首先,我尝试将is_power_of_two 定义为模块中的一个函数,但它不起作用,我得到了这个错误:

cannot invoke local is_power_of_two/1 inside guard.

按照这个blog post,我尝试将其定义为以下宏:

defmodule MyModule.Util do
  defmacro is_power_of_two(x) do
    quote do
      (unquote(x) != 0)
        and ((unquote(x) &&& (unquote(x) - 1)) == 0)
    end
  end
end

效果不佳,我收到以下错误:

cannot invoke local &&&/2 inside guard

似乎无法从宏展开后的when 子句中调用按位&&& 运算符。

如何执行需要包含按位运算符的守卫的匹配?

【问题讨论】:

    标签: pattern-matching elixir


    【解决方案1】:

    错误信息具有误导性。您只是在MyModule.Util 中缺少import Bitwise。如果我添加import,则代码有效:

    defmodule MyModule.Util do
      import Bitwise
    
      defmacro is_power_of_two(x) do
        quote do
          (unquote(x) != 0) and ((unquote(x) &&& (unquote(x) - 1)) == 0)
        end
      end
    end
    
    defmodule MyModule do
      import MyModule.Util
    
      def my_func(n) when is_power_of_two(n) do
        true
      end
      def my_func(_), do: false
    end
    
    IO.inspect MyModule.my_func(128)
    IO.inspect MyModule.my_func(129)
    

    输出:

    true
    false
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-31
      • 1970-01-01
      • 2016-02-01
      • 1970-01-01
      相关资源
      最近更新 更多