clojure-基本语法-流程控制(二)

来源:互联网 发布:mysql表格创建 编辑:程序博客网 时间:2024/05/16 08:56
二、异常处理 
Clojure代码里面抛出来的异常都是运行时异常。当然从Clojure代码里面调用的java代码还是可能抛出那种需要检查的异常的。try,catch,finally 以及throw 提供了和java里面类似的功能: 
try、catch、throw、finally: 
Java代码  收藏代码
  1. user=> (try (throw (Exception. "error")) (finally (println "final")))  
  2. final  
  3. Exception error  user/eval310 (NO_SOURCE_FILE:1)  


Java代码  收藏代码
  1. user=> (try (/ 3 0) (catch Exception e (println e)))  
  2. #<ArithmeticException java.lang.ArithmeticException: Divide by zero>  
  3. nil  


assert: 
它测试一个表达式, 如果这个表达式的值为false的话,它会抛出异常。 
Java代码  收藏代码
  1. user=> (assert true)  
  2. nil  
  3. user=> (assert false)  
  4. AssertionError Assert failed: false  user/eval317 (NO_SOURCE_FILE:1)  
  5. user=> (assert nil)  
  6. AssertionError Assert failed: nil  user/eval319 (NO_SOURCE_FILE:1)  
  7. user=> (assert 0)  
  8. nil  
  9. user=> (assert [1 2 3])  
  10. nil  
  11. user=> (assert "foo")  
  12. nil  


三、基于函数的流程控制 
repeatedly: 
repeatedly字面意思为重复函数。一般的用法如下: 
Java代码  收藏代码
  1. user=> (repeatedly 5 #(rand-int 11))  
  2. (6 8 2 6 6)  

重复产生5次随机数。rand-int 11表示0至11的随机数。 
这里顺便提一下repeat函数:repeat函数接受一/两个常量参数,用法如下: 
Java代码  收藏代码
  1. user=> (repeat 5 (int (rand-int 100)))  
  2. (30 30 30 30 30)  

当repeat、repeatedly函数只接受一个参数时(即没有重复次数的参数),需要配合take来中止,否则会产生内存溢出的错误。如下: 
Java代码  收藏代码
  1. user=> (repeatedly #(rand-int 11))  
  2. OutOfMemoryError Java heap space  java.util.Arrays.copyOf (Arrays.java:2882)  
  3. user=> (take 5 (repeatedly #(rand-int 11)))  
  4. (10 7 0 2 8)  


iterate: 
迭代函数形式如下: 
(iterate f v) 
相当于: 
while(true) { v = f(v) } 
所以一般要配合(take n sequence)来中止: 
Java代码  收藏代码
  1. user=> (take 10 (iterate inc 5)) ; (5 6 7 8 9 10 11 12 13 14)  
  2. user=> (take 10 (iterate #(+ % 55)) ; (5 10 15 20 25 30 35 40 45 50)  
  3. user=> (take 10 (iterate #(* % 22)) ; (2 4 8 16 32 64 128 256 512 1024)  


四、基于序列的流程控制 
dotimes: 
dotimes 会执行给定的表达式一定次数, 一个本地binding会被给定值:从0到一个给定的数值。如下: 
Java代码  收藏代码
  1. user=> (dotimes [num 3] (println "number:" (inc num)))  
  2. number: 1  
  3. number: 2  
  4. number: 3  
  5. nil  


doseq: 
doseq和for的语法是一样的,只不过for返回lazy seq而doseq接受任意数量的表达式, 以有副作用的方式执行它们, 并且返回nil 
Java代码  收藏代码
  1. user=> (doseq [i (range 10)] (println i))  
  2. 0  
  3. 1  
  4. 2  
  5. 3  
  6. 4  
  7. 5  
  8. 6  
  9. 7  
  10. 8  
  11. 9  
  12. nil  
  13. user=> (doseq [i [1 2 3] j [10 20]] (println i "-" j))  
  14. 1 - 10  
  15. 1 - 20  
  16. 2 - 10  
  17. 2 - 20  
  18. 3 - 10  
  19. 3 - 20  
  20. nil  


for: 
for、doseq都支持遍历多个集合(最右边的最快),同时还可以用:when 和 :while来过滤。 
Java代码  收藏代码
  1. user=> (for [x (range 3 7)] (* x x))  
  2. (9 16 25 36)  
  3.   
  4. user=> (for [x [0 1 2 3 4 5] :let [y (* x 3)] :when (even? y)] y)  
  5. (0 6 12)  

上面第二条语句可理解为:先定义x为集合,再使用let将y赋值为x*3,最后判断y是否为偶数,偶数才返回
0 0
原创粉丝点击