让我说我有:
[ X || X<- L, some_expensive_boolean(X), some_expensive_boolean2(X)]
对于任何X in L
,some_expensive_boolean(X)
是否为false
,some_expensive_boolean2(X)
是否已执行?
答案 0 :(得分:3)
基于以下内容的短路:
${GEN_HEADER_A}
执行:
-module(shortcircuit).
-export([test/0]).
test() ->
L = [1, 2, 3],
[ X || X <- L, some_expensive_boolean(X), some_expensive_boolean2(X)].
some_expensive_boolean(X) ->
io:format("In some_expensive_boolean: ~p~n", [X]),
false.
some_expensive_boolean2(X) ->
io:format("In some_expensive_boolean2: ~p~n", [X]),
true.
答案 1 :(得分:3)
答案是否定的。它被短路了。
1> [ X || X <-[1,2], begin io:format("Test 1: ~p~n", [X]), X rem 2 =:= 0 end, io:format("Test 2: ~p~n", [X]) =:= ok ].
Test 1: 1
Test 1: 2
Test 2: 2
[2]
答案 2 :(得分:3)
TL; DR:不,some_expensive_boolean2/1
未被调用。
有几种方法可以验证这一点。
-module(lc).
-export([lc/1]).
lc(L) ->
[X || X <- L, f(X), g(X)].
f(X = 2) ->
erlang:display({f, 2}),
false;
f(X) ->
erlang:display({f, X}),
true.
g(X) ->
erlang:display({g, X}),
true.
然后在Erlang shell上:
1> lc:lc(lists:seq(1, 4)).
{f,1}
{g,1}
{f,2} %% g is not called here
{f,3}
{g,3}
{f,4}
{g,4}
[1,3,4]
使用+to_core
选项编译模块将生成带有Core Erlang代码的lc.core
文件,该文件看起来有点像Erlang,但有自己的语法,但语义非常相似。
erlc +to_core lc.erl
生成的代码非常详细,所以我不会在这里粘贴它,但要点是有两个嵌套的case
表达式,一个调用f/1
,其子句与{匹配{1}}包含调用true
的其他case
。
答案 3 :(得分:1)
让我们创建一个例子:
$ cat test.erl
-module(test).
-export([show/0]).
show() ->
[ X || X <- [1,2,3,4,5], bigger(X), smaller(X)].
bigger(X) ->
io:format("bigger ~p~n", [X]),
X > 2.
smaller(X) ->
io:format("smaller ~p~n", [X]),
X < 4.
并测试它:
14> c(test).
{ok,test}
15> test:show().
bigger 1
bigger 2
bigger 3
smaller 3
bigger 4
smaller 4
bigger 5
smaller 5
[3]
所以答案是:NO。