字面量
数字类型
42 ; 长整型,64位,范围 -2^63 to 2^63-1
6.022e23 ; 64位双精度浮点数
42N ; 任意精度整数
1.0M ; 任意精度定点小数
22/7 ; 比值
字符类型
"hello" ; 字符串
\e ; 字符
其他类型
nil ; 空值
true,false ; 布尔值
#"[0-9]+" ; 正则表达式
:alpha ; 关键字
:release/alpha ; 带命名空间的关键字
map ; 符号
+ ; 符号,大多标点符号都可以是符号
clojure.core/+ ; 命名空间符号
上面的所有文字都是有效的Clojure表达式
Clojure还包括四种集合类型的字面量语法:
'(1 2 3) ; list列表
[1 2 3] ; vector向量
#[1 2 3] ; set 集合
{:a 1, :b 2} ; map 键值对
Evalution求值
传统Java Evalution求值方式
在Java中,源代码(.java文件)由编译器(javac)读取为字符,它生成可由JVM加载的字节码(.class文件)。
Clojure Evalution方式
在Clojure中,源代码由Reader读取成字符。 Reader可以从.clj文件中读取源代码,也可以交互式地给出一系列表达式。 Reader生成Clojure数据结构。 然后,Clojure编译器生成JVM的字节码。
以下2点很重要:
1.源代码的单位是Clojure表达式,而不是Clojure源文件。 源文件作为一系列表达式被读取,就像在REPL中以交互方式键入这些表达式一样。
2.分离阅读器和编译器的分离很关键,它为宏提供了空间。 宏是一种特殊的函数,它接受代码(作为数据),并发射代码(作为数据)。
结构与语义
Clojure表达式:
此图说明了绿色语法(由Reader生成的Clojure数据结构)与蓝色语义(Clojure运行时如何理解该数据)之间的区别。
除符号和列表外,大多数文字Clojure表单都会自行evaluate。 在evaluate时,符号用于指代其他内容,返回它们所引用的内容。 列表(如图中所示)被evaluate为调用。
在图中,(+ 3 4)被读作包含符号(+)和两个数字(3和4)的列表。 第一个元素(找到+的地方)可以称为“函数位置”,也就是找到要调用的东西的地方。 虽然函数是一个显而易见的调用,但运行时,宏和一些其他可调用的东西也有一些特殊的运算符。
上述表达式被evaluate为:
1. 3 和 4被evaluate成它们自己,即长整数
2. + 号被evaluate为一个实现了+功能的方法
3. list被evaluate为函数调用,调用了已3和4为参数的+方法
许多语言都有语句和表达式,其中语句具有一些有状态效果但不返回值。 在Clojure中,一切都是对一个值进行evaluate的表达式。 一些表达(但不是大多数)也有副作用。
阻止求值
有时候阻止求值是很有用的,特别是为了使用符号本身和list的时候,用法
user=> 'x ;x
user=>'(123) ;(1 2 3)
REPL
大多数REPL环境都支持一些技巧来帮助交互式使用。 例如,一些特殊符号记住最后三个表达式求值的结果:
*1 (最后一个的结果)
*2 (最后2个表达式的结果)
*3 (最后3个表达式的结果)
此外,还有一个命名空间clojure.repl,它包含在标准Clojure库中,提供了许多有用的功能。 要加载该库并使其功能在我们当前的上下文中可用,请调用:
(require '[clojure.repl :refer :all])
我们现在可以访问一些在REPL中有用的附加功能:doc, find-doc, apropos, source, and dir
doc是一个显示任何函数文档的函数,如
如果你不确定要使用哪个函数? 您可以使用apropos命令查找与特定字符串或正则表达式匹配的函数。
你还可以扩大搜索范围,以使用find-doc包含文档字符串
如果您想查看特定命名空间中函数的完整列表,可以使用dir函数。 在这里我们可以在clojure.repl命名空间中使用它:
查看源代码 source函数
资源:https://clojure.org/api/cheatsheet
Clojure基础
def
当你在REPL中对表达式求值时,保存一段数据以供日后使用会很有用。 我们可以用def做到这一点
def是一种特殊形式,它将当前命名空间中的符号(x)与值(7)相关联。 这种联系称为一个var(变量)。 在大多数实际的Clojure代码中,vars应该被引用为常量值或函数,但是为了方便起见,在REPL中工作时通常会定义和重新定义它们。
注意上面的返回值是#'user / x - 这是var:#'的文字表示,后跟命名空符号。 user是默认名称空间。
回想一下,通过查找它们引用的内容来评估符号,这样我们就可以通过使用符号来获取值:
打印Printing
学习语言时最常见的事情就是打印出值。 Clojure提供了几种打印值的功能:
人类可读的函数会将特殊的打印字符(如换行符和制表符)转换为预期的形式,并打印不带引号的字符串。 我们经常使用println来调试函数或在REPL上打印一个值。 println接受任意数量的参数,并在每个参数的打印值之间插入一个空格:
println函数具有副作用(打印)并因此返回nil。
请注意,上面的“what is this:”不会打印周围的引号,也不是Reader可以以相同方式再次读取的字符串。 为此,请使用机器可读的版本prn:
请注意,这打印结果是Reader可以再次读取的有效形式。 human-和readable-打印功能在不同的环境中都很有用。
测试
1.使用REPL计算7654和1234
2.将以下代数表达式重写为Clojure表达式:7 + 3 * 4 + 5 ) / 10
3.使用REPL文档函数,找到rem和mod函数的文档,根据文档比较提供的表达式
4.使用find-doc,找到打印最新REPL异常的堆栈跟踪的函数
翻译自: https://www.clojure.org/guides/learn/syntax
翻译者:Eyck Luo
网友评论