clojure基础入门(一)

最近在看storm的源码,就学习分享下clojure语法。

阅读目录:

  1. 概述
  2. 变量
  3. 运算符
  4. 流程控制
  5. 总结

概述

clojure是一种运行在JVM上的Lisp方言,属于函数式编程范式,它和java可以方便的互相调用,这样开发的程序可以很好的结合java和clojure的优点(storm),这跟Net中C#和F#的角色一样。

安装java1.6以上的JDK,下载地址。 下载clojure的环境 包,下载地址。 解压后用命令行进入到clojure目录下,输入下面命令进入REPL命令行交互界面:

java -cp clojure-1.7.0.jar clojure.main

欢迎进入clojure的世界。 

变量

Clojure中的变量可以def关键字来声明: 

clojure数据类型是弱类型,对应java中的object,然后通过变量名直接调用。

类似c#中代码:

 object greet = "Good Morning";
  Console.WriteLine(greet);

Clojure语法是把代码元素用小括号形式括起来,以空格来分割元素,使其像填充列表一样来编写代码。

 (str "Hello World!")

函数式编程中以函数为第一类对象,其小括号后面第一个元素被Clojure解释器当成一个函数或宏,其后面的都会被当成参数,如上"hello world"是被当成参数传入str函数进行输出。

类似C#代码:

 Console.WriteLine("Hello World!");

一个变量可以重复赋值,也可以是不同类型:

def可以把函数赋值给一个变量,函数变量不能直接调用,需要加上括号: 

类似c#代码: 

Action func = () => { Console.WriteLine("Hello World"); };
func();

运算符

clojure使用前置运算符,分号(;)表示后面跟的是注释。 加减乘除:

(+ 1 1) ; => 2
(- 2 1) ; => 1
(* 1 2) ; => 2
(/ 2 1) ; => 2

增量,接受一个数值加1后范围,类似C#中的i++。

 (inc 5) ;=>6

减量:

 (dec 5) ;=>4

求商函数:

 (quot 5 2) ;=>2 

求余函数:

(quot 5 2) ;=>1

小于(<):

 (< 5 6) ;=>true

小于等于 (<=):

(<= 5 5) ;true

大于(>):

 (> 8 5) ;=>true

大于等于 (>=) :

(<= 5 5) ;true

等号 =

(= 1 1) ; => true
(= 2 1) ; => false
(= 1 "1") ;=> false

同样的把前置运算符理解为函数,后面为参数。

函数

clojure中以函数为第一类对象,其小括号后面第一个元素被Clojure解释器当成一个函数或宏,其后面的都会被当成参数。 定义函数用defn,跟定义变量的def类似:

(defn Get [] "Hello World") ;=>"Hello World"

下面定义了get函数,中括号为函数的参数,输出Hello World字符串。加参数后,再次调用需要传入值,如果不传会报异常。

下面在函数内部使用a函数参数,如果想要拼接的话,可以在内部使用str函数,用它返回的值当成Get函数的参数: 

多个参数表示形式:[arg1,arg2]

流程控制

判断if

这里有三层嵌套,首先(= age 18)来判断返回是否等于18,作为if判断该返回哪个字符串的依据,再根据if确定的字符串作为函数的返回值。 注意if是不是函数或宏,而是叫做special form(特殊形式),而且没有else,用空白或换行即表示else,不用显式return,clojure会将最后一个表示的值作为函数的返回值。

谓词函数

谓词函数是一个判断式,一个返回bool值的函数或者仿函数,用来测试条件是否成立。 与或非(and or not):

clojure中(lisp习惯)有个规定:对于判断功能的函数,函数名后面都有一个“?”号。所以只要看到后面带问号的函数名,就知道这一定是一个判断语句。

user=> (fn? quot) ;判断quot是不是一个函数true 

测试一个对象的类型的谓词:class?,coll?,decimal?,delay?,float?,fn?,instance?,integer?,isa?,keyword?,list?,macro?,map?,number?,seq?,set?,string?,vector?。

测试两个值之间关系的谓词有:<,<=,=,not=,==,>,>=,compare,distinct? , identical?。

测试逻辑关系的谓词有:and,or,not,true?,false?,nil?。

测试数字的谓词有:even?,neg?,odd?,pos?,zero?。

总结

Clojure里面的每个操作被实现成以下三种形式:

  •  函数(function)     文中以defn定义的。
  •  宏(macro)           Clojure中几乎所有的函数和宏都是用Clojure代码实现的,关于宏后面再说。
  •  special form        文中出现的if就是,其他还包括catch,def,do,dot (‘.’),finally,fn,if,let,loop,monitor-enter,monitor-exit,new,quote,recur,set!,throw,try,var。

博客园的代码高亮不支持Clojure。

[0]  http://clojure.org/[1] http://xumingming.sinaapp.com/302/[2] http://huangz.iteye.com/blog/1325228[3] http://segmentfault.com/a/1190000000414279#articleHeader0

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏逸鹏说道

Python3 与 C# 基础语法对比(List、Tuple、Dict专栏)

Python3 与 C# 基础语法对比(基础知识场):https://www.cnblogs.com/dotnetcrazy/p/9102030.html

23310
来自专栏服务端技术杂谈

Java编码规范

命名 类名使用UpperCamelCase风格。 领域模型相关命名:DO / DTO / VO / DAO等。 方法名,参数名,成员变量,局部变量都统一使用lo...

2994
来自专栏技术博客

C#简单的面试题目(二)

实例化对象  new Class();        隐藏基类方法,即覆盖方法  public  new xxx(){}

1021
来自专栏java 成神之路

Java 动态代理 原理解析

31610
来自专栏开发与安全

从零开始学C++之模板(二):类模板、Stack的类模板实现(自定义链栈方式,自定义数组方式)

一、类模板 类模板:将类定义中的数据类型参数化 类模板实际上是函数模板的推广,可以用相同的类模板来组建任意类型的对象集合 (一)、类模板的定义 templ...

2130
来自专栏柠檬先生

Sass 基础(五)

@if   @if 指令是一个SassScript,它可以根据条件处理样式块,如果条件为true返回一个样式块,反之   false 返回另一个样式块,在S...

2268
来自专栏小灰灰

JDK容器学习之Queue: ArrayDeque

数组双端队列 ArrayDeque 双端队列,表示可以添加元素到(或删除,获取)队列头也可以添加元素到(或删除,获取)队列尾 ? 1. 底层数据结构 类中定义成...

1896
来自专栏微信公众号:Java团长

细说JDK动态代理的实现原理

来源:blog.csdn.net/mhmyqn/article/details/48474815

642
来自专栏mySoul

TypeScript 接口

// 注意在上方中并不会对静态的,进行检查。只会对非静态的部分,即非构造函数部分进行检查

1224
来自专栏闵开慧

java概念1

public static void main(String[] args) {//其中[]也可以写在args后面,args也可以随便写成其他字母,例如asd...

34511

扫码关注云+社区