本文来自网易云社区
作者:李诺
" Clojure is elegant and pragmatic; it helps me focus more on solving business problems."
不同于Java这类静态语言, Clojure是动态语言,动态类型意味着这些类型会在代码运行时由Clojure动态的推导出来,编译时不作任何限制。
user=> (defn f1 [a b] (+ "1" 2))#'user/f1
user=> (f1 1 2)ClassCastException java.lang.String cannot be cast to java.lang.Number clojure.lang.Numbers.add (Numbers.java:128)
对比上面的两端代码,即使函数f1中含有类型有误的表达式(+ "1" 2)也是可以定义的。然而一旦运行的时候(我们随意给了两个没有用到的参数),函数+会尝试将"1"和2投射(cast)到Java中的Number类,这时候代码中的类型错误就会以ClassCastException抛出来,因为字符串"1"是无法被投射到Number类的。
注意: 投射(cast)和转换(convert)并不一样,cast一般是将一个子类的成员投射到它的超类上,而像Javascript中"1" + 2 = 3所做的就是隐式转换了。Clojure的原生函数没有使用隐式转换。
所以我们在写代码的时候一般不需要给定数据类型,但这不意味着类型就不重要了。
为了更好地认识Clojure的类型,首先要会用一个函数: type
user=> (doc type)-------------------------clojure.core/type([x]) Returns the :type metadata of x, or its Class if nonenil
我们可以用这个函数获取定义中的元数据中的:type项,如果没有这项,那么就返回它的类名。
基本数据类型
我们先来看一些常见的值被推导的默认类型:
数值
-
整数 1,2,3...
-
user=> (type 1)java.lang.Long
Clojure的整数默认使用Java中的Long基础类型,
-
小数 1.414,π...
-
user=> (type Math/PI)java.lang.Double
小数使用Java中的Double类型。
如果我们想要使用其他一些java中的基本类型的整数或者浮点数,我们可以使用
user=> (type (int 1))java.lang.Integeruser=> (type (float 3.14))java.lang.Float
这类强制转换(Coerce)函数来生成。
有兴趣的同学可以去试试 (type 1111111111111111111111111111111111111111) 和 (type (/ 1 2)) 是什么类型的。
字符串
user=> (type \a)java.lang.Characteruser=> (type "Hello")java.lang.String
字符和字符串同样也是来自Java。
