clojure是基于jvm的语言,就是说clojure会被编译成字节码被jvm执行。可是clojure能作的可不单单是被编译成字节码,它提供了一套API让用户与java交互。所以clojure能够直接调用java世界中那些丰富庞大的优秀库了。 java
=>12.56 12.56在clojure中,咱们使用数据时彷佛并无像其余语言那样须要一些特殊的处理或者声明。可是,clojure在底层实际建立了java对象,并指定了对应的java类型。咱们能够经过class函数来看一下编译器为咱们建立的数据的类型。
=>(class 12.56) java.lang.Double上面咱们能够看出,clojure自动为咱们建立了一个Double类型的java对象。
若是咱们想在clojure指定对应的java类型,能够这么作: jvm
=>(new java.lang.Float 12.56) 12.56 =>(class (new java.lang.Float 12.56)) java.lang.Floatnew 也是一个函数,咱们使用它建立了一个Float类型的对象,貌似比java还麻烦。clojure给咱们提供了一个更简洁的语法来作一样的事情。咱们在对应的构造函数名字后加一个点,而后后面依次写上构造函数须要的参数便可。
=>(Float. "12.56") 12.56 =>(class (Float. "12.56")) java.lang.Float这里 Float. 就是Float的构造函数名加上一个点。这可不是clojure的函数调用。咱们可使用fn?测试一下,Floag.并非函数。应该只是clojure的特殊的语法调用吧。
下面是一些将字符串转换为数字的例子: 函数
=>(+ "12.56" "5.92") java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number =>(class "12.56") java.lang.String =>(+ (Float. "12.56")(Float. "5.92")) 18.48 =>(+ (Float. "12.5648230948234")(Float. "5.92")) 18.484823 =>(+ (Double. "12.5648230948234")(Double. "5.92")) 18.484823094823398
clojure自己并无专门的日期和时间处理函数。不过不用担忧,java有的功能,clojure基本上均可以去调用。并且一旦咱们用clojure函数将java的方法包装后,咱们后面的调用就不再会和java打交道了。 测试
下面就看看如何使用java接口来创造咱们本身的日期时间函数。让咱们从调用系统当前时间开始吧。这一次咱们先采用一种“斜线调用”形式。咱们使用斜线一次隔开类名和调用的静态方法名称。咱们将要调用java中的 System.currentTimeMillis()方法来获取当前系统时间的毫秒数。 spa
=>(defn msec [] ;;使用函数msec包装 (System/currentTimeMillis)) ;;这里的斜线至关于java中的 "." #'user/msec =>(msec) ;;调用msec,返回当前系统时间毫秒数 1307328017335 =>(msec) 1307662973116 =>(> 1307328017335 1307662973116) false =>(> 1307662973116 1307328017335) true
上面是静态方法调用的展现,下面再来看看若是调用实例方法。让咱们建立两个java.util.Date对象。注意,以前咱们使用的都是java.lang下面的类,因此不须要手动导入。非lang包下的必须手动导入(和java同样同样的)。 翻译
=>(Date.) ;;导入前,找不到Date类 java.lang.IllegalArgumentException: Unable to resolve classname: Date... =>(import java.util.Date) ;;手动导入Date (语法都和java同样) java.util.Date =>(Date.) ;;再次建立Date对象 #<Date Sun Jun 05 20:48:19 MDT 2011> =>(class (Date.)) ;;查看一下对象类型,确实是 java.util.Date java.util.Date
如今咱们来用clojure来包装一下,咱们创造一个名为date的函数。该函数有两种参数形式:无参数和接受毫秒值(对应Date 的无参构造函数和 Date(long time)构造函数)。 code
=>(defn date ;;使用函数date封装java API ([](Date.)) ;;第一种是无参数模式 ([systime](Date. systime))) ;;第二种是接受一个参数 #'user/date =>(date) ;;调用date函数,无参数 #<Date Sun Jun 05 20:41:42 MDT 2011> =>(date 1307328017335) ;;调用date函数,传入一个long值 #<Date Sun Jun 05 20:40:17 MDT 2011>为了让咱们时间处理在强大点,咱们在利用java库中的 SimpleDateFormat类将时间转换成特定形式的字符串。
=>(import java.text.SimpleDateFormat) ;;导入须要的类 java.text.SimpleDateFormat =>(defn format-date ;;使用自定义函数封装 ([](format-date (date) "yyyy MM dd HH mm ss")) ([x](if (string? x) (format-date (date) x) (format-date x "yyyy MM dd HH mm ss"))) ([dt fmt](.format (SimpleDateFormat. fmt) dt))) #'user/format-date =>(format-date) "2011 06 04 17 50 21" =>(format-date (date 404534000000)) "1982 10 26 20 33 20" =>(format-date "yyyy/MM/dd HH:mm:ss") "2011/06/04 17:51:00" =>(format-date (date 404534000000) "yyyy/MM/dd HH:mm:ss") "1982/10/26 20:33:20"其余没有什么难点,都是以前说过的内容,咱们主要解释上面代码中下面这一句的意义:
([dt fmt](.format (SimpleDateFormat. fmt) dt)))[dt fmt]是参数列表,这个没什么特别的东西。主要看看函数体。 .format 是方法名 (SimpleDateFormat. fmt)最终返回的是 SimpleDateFormat类型的对象(至关于调用 new SimpleDateFormat(fmt)) ,dt 是参数因此整个意思是调用实例 (SimpleDateFormat. fmt)的format 方法,并传入参数dt。翻译成java代码就是:
(new SimpleDateFormat(fmt)).format(dt)很简单吧。我的以为使用clojure封装后的java代码比本来的java API更要紧凑和灵活。这主要依靠了clojure这种动态语言+函数式语言的N多优点。