我有以下函数,只需要匹配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
运算符。
如何执行需要包含按位运算符的保护的匹配?
答案 0 :(得分:2)
错误消息具有误导性。您在import Bitwise
中错过了MyModule.Util
。如果我添加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