为什么Clojure中两个filter函数输出不同?双匿名函数写法合法吗?
Clojure filter代码差异问题解答
输出结果不同的根本原因
- Clojure中的
and是短路求值宏,而非普通函数:它会按顺序对传入的参数求值,遇到第一个逻辑假的参数就直接返回该值,若所有参数都为逻辑真,则返回最后一个参数的求值结果。 - 第一段代码的
(and #(= (rem % 2) 1) #(= (rem % 3) 0))是作为filter的第一个参数直接传入的,会在filter执行前就完成求值:两个匿名函数在Clojure中都属于逻辑真值,因此整个and表达式最终返回的是最后一个匿名函数#(= (rem % 3) 0)。也就是说第一段代码的filter实际仅用「能被3整除」作为过滤条件,因此会返回0、3、6等所有符合该条件的数。 - 第二段代码的
and写在匿名函数内部,每个被遍历的自然数传入匿名函数时,才会执行and对应的判断逻辑:需要同时满足「是奇数」且「能被3整除」,因此最终返回的是能被3整除的奇数,即3、9、15等结果。
第一种写法的合法性说明
第一种写法语法上是合法的,代码可以正常运行不会抛出语法错误,但逻辑上完全不符合预期:开发者原本想表达两个过滤条件同时生效,实际最终仅最后一个条件生效,属于典型的逻辑错误。
内容的提问来源于stack exchange,提问作者Likepineapple
相关产品推荐
相关产品推荐

