1.基本例子

; 分号作为注释的开始

; Clojure 用一种把元素用括号括起来的像列表一样的方式来书写,元素之间用空格隔开
; clojure 解释器会把第一个元素当做是函数或者宏调用,其他的都作为参数
; 下面这个函数用于设置当前的命名空间
(ns test) ; 更多基本的例子: ; str 函数会用它所有的参数创造一个字符串
(str "Hello" " " "World") ; => "Hello World" ; 数学运算很直观,不过是前缀表达式
(+ 1 1) ; => 2
(- 2 1) ; => 1
(* 1 2) ; => 2
(/ 2 1) ; => 2 ; 相等比较使用 “=”符号
(= 1 1) ; => true
(= 2 1) ; => false ; 你也不必担心逻辑运算
(not true) ; => false ; 嵌套方式正如你预料的那样
(+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2

2. 类型系统

;;;;;;;;;;;;;

; Clojure 使用java对象类型来表示 布尔值、字符串和数字
; 使用 `class`函数来检测它们.
(class 1) ; 整形字面值默认是java中的Long类型
(class 1.); 浮点字面值对应着java中的Double类型
(class ""); 字符串总是用双引号括起来,并且对应着java中的Sring类型
(class false) ;布尔值对应着java中的Boolean类型
(class nil); null值被称为 nil(英语含义:无、零点) ; 如果你想创建一列数据字面值, 使用一个单引号 ' 来防表达式被解析执行
'(+ 1 2) ; => (+ 1 2) ;这里没有返回3
; (上面表达式和(quote (+ 1 2)) 等价,不过更简洁 ; 你可以运算一个引用列表
(eval '(+ 1 2)) ; => 3

3. 集合和序列

;;;;;;;;;;;;;;;;;;;

; 向量和列表也是java类哦!!
(class [1 2 3]); => clojure.lang.PersistentVector
(class '(1 2 3)); => clojure.lang.PersistentList ;书写一个列表形如(1 2 3)一样简单, 但是我们不得不把它“引”(前面加个单引号)起来
;这样就能防止解释器把它当做一个函数来解析
;另外,(list 1 2 3) 和 '(1 2 3) 等价 ;列表和向量都是集合:
(coll? '(1 2 3)) ; => true
(coll? [1 2 3]) ; => true ; 只有列表是序列.(序列是有顺序的)
(seq? '(1 2 3)) ; => true
(seq? [1 2 3]) ; => false ; 序列是列表一种逻辑上的接口,可以懒加载.
; "懒" 意味着可以定义无穷序列,就像下面一样:
(range 4) ; => (0 1 2 3)
(range) ; => (0 1 2 3 4 ...) (一个无穷序列)
(take 4 (range)) ; (0 1 2 3) ; 使用cons 来追加一个元素到列表或者向量的头部
(cons 4 [1 2 3]) ; => (4 1 2 3)
(cons 4 '(1 2 3)) ; => (4 1 2 3) ; 使用conj追加一个元素到列表的头部,或者向量的尾部,
(conj [1 2 3] 4) ; => [1 2 3 4]
(conj '(1 2 3) 4) ; => (4 1 2 3) ; 使用concat来连接列表和向量
(concat [1 2] '(3 4)) ; => (1 2 3 4) ; 使用filter, map 来进行列表计算
(map inc [1 2 3]) ; => (2 3 4)
(filter even? [1 2 3]) ; => (2) ; 使用reduce 来进行化繁为简 (map/reduce 思想就来自于lisp)
(reduce + [1 2 3 4])
; = (+ (+ (+ 1 2) 3) 4)
; => 10 ; Reduce 可以使用一个初始值
(reduce conj [] '(3 2 1))
; = (conj (conj (conj [] 3) 2) 1)
; => [3 2 1]

4. 函数

;;;;;;;;;;;;;;;;;;;;;

; 使用fn来创建一个函数。所有的函数都有返回值,就是它的最后一个表达式
(fn [] "Hello World") ; => fn ; (你需要额外的括号去调用它)
((fn [] "Hello World")) ; => "Hello World" ;你可以使用def来创建变量
(def x 1)
x ; => 1 ; 将函数赋值给一个变量
(def hello-world (fn [] "Hello World"))
(hello-world) ; => "Hello World" ; 你可以使用defn来简化定义过程
(defn hello-world [] "Hello World") ;[] 是函数的参数列表
(defn hello [name]
(str "Hello " name))
(hello "Steve") ; => "Hello Steve" ; 你也可以使用下面这种简写方式
(def hello2 #(str "Hello " %1))
(hello2 "Fanny") ; => "Hello Fanny" ; 你可以创建拥有可变参数的函数
(defn hello3
([] "Hello World")
([name] (str "Hello " name)))
(hello3 "Jake") ; => "Hello Jake"
(hello3) ; => "Hello World" ; 函数允许将参数打包成列表 (有点类似python中的*)
(defn count-args [& args]
(str "You passed " (count args) " args: " args))
(count-args 1 2 3) ; => "You passed 3 args: (1 2 3)" ; 你可以将普通参数和列表参数混合使用
(defn hello-count [name & args]
(str "Hello " name ", you passed " (count args) " extra args"))
(hello-count "Finn" 1 2 3)
; => "Hello Finn, you passed 3 extra args"

5. 哈希表

;;;;;;;;;;

(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap

; 关键字类似字符串,但是做了一些性能上的优化
(class :a) ; => clojure.lang.Keyword ; Maps 的键可以是任意类型,但是通常推荐使用keywords
(def stringmap (hash-map "a" 1, "b" 2, "c" 3))
stringmap ; => {"a" 1, "b" 2, "c" 3} (def keymap (hash-map :a 1 :b 2 :c 3))
keymap ; => {:a 1, :c 3, :b 2} (不保证顺序) ; 顺便说一下, 逗号只是为了看着更清晰,其他都和空格一样,什么都不做. ; 从一个map中检索一个值,可以直接把这个map当做函数调用(这个NB)
(stringmap "a") ; => 1
(keymap :a) ; => 1 ; 关键字也可以当做函数来调用,从一个map中检索值(这个更NB)
(:b keymap) ; => 2 ; stings 可没有这个功能,所以下面会抛出异常。(这也是为什么推荐使用keywords)
;("a" stringmap)
; => Exception: java.lang.String cannot be cast to clojure.lang.IFn ; 检索一个不存在的值会返回nil
(stringmap "d") ; => nil ; 使用assoc 向一个map中添加新的键值对。
(assoc keymap :d 4) ; => {:a 1, :b 2, :c 3, :d 4} ; 请记住, clojure 类型是不可变的!
keymap ; => {:a 1, :b 2, :c 3} ; 使用dissoc 来删除key(可以删除多个)
(dissoc keymap :a :b) ; => {:c 3}

6. 集合

;;;;;;

(class #{1 2 3}) ; => clojure.lang.PersistentHashSet
(set [1 2 3 1 2 3 3 2 1 3 2 1]) ; => #{1 2 3} ; 使用con来添加新值
(conj #{1 2 3} 4) ; => #{1 2 3 4} ; 使用disj删除原有值
(disj #{1 2 3} 1) ; => #{2 3} ; 直接将set当做函数来测试是否包含某个值(NB)
(#{1 2 3} 1) ; => 1 (有就返回原有的值)
(#{1 2 3} 4) ; => nil (没有就返回nil)

7. 一些有用的形式

;;;;;;;;;;;;;;;;;

; clojure中的逻辑结构都是宏, 看起来也没什么不同
(if false "a" "b") ; => "b"
(if false "a") ; => nil ; 使用let 来创建临时绑定
(let [a 1 b 2]
(> a b)) ; => false ; 执行多条语句,返回最后一条语句
(do
(print "Hello")
"World") ; => "World" (prints "Hello") ; 所有的函数都包含一个隐式的do
(defn print-and-say-hello [name]
(print "Saying hello to " name)
(str "Hello " name))
(print-and-say-hello "Jeff") ;=> "Hello Jeff" (prints "Saying hello to Jeff") ; let绑定也是哦
(let [name "Urkel"]
(print "Saying hello to " name)
(str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel")

8. 模块

;;;;;;;;;;;;;;;

; 使用“use”来获得一个模块中所有的函数
(use 'clojure.set) ; 现在我们可以使用集合操作
(intersection #{1 2 3} #{2 3 4}) ; => #{2 3} 求交集
(difference #{1 2 3} #{2 3 4}) ; => #{1} 求差集 ; 你可以只导入一个函数子集(例如下面只包含交集函数)
(use '[clojure.set :only [intersection]]) ; 使用reqire来导入一个模块
(require 'clojure.string) ; 使用/从一个模块中调用函数
(clojure.string/blank? "") ; => true ; 你可以在导入模块的时候自定义名称
(require '[clojure.string :as str])
(str/replace "This is a test." #"[a-o]" str/upper-case) ; => "THIs Is A tEst."
; (#"" denotes a regular expression literal) ; 你可以使用":require" 从一个命名空间中引入模块(use也可以,但是别这么做)
; 如果你使用:require的话,就没必要把模块“引”(前面加个单引号)起来了.
(ns test
(:require
[clojure.string :as str]
[clojure.set :as set]))

9. Java

;;;;;;;;;;;;;;;;;

; java 拥有一个庞大的各种用途的标准库,你一定迫不及待想学习如何在clojure中使用这些库

; 使用import类引入java模块(这个还好没变化)
(import java.util.Date) ; 你也可以从一个命名空间中引入
(ns test
(:import java.util.Date
java.util.Calendar)) ; 类名字后加个”."用来创建一个对象
(Date.) ; <a date object> ; 使用. 来调用方法. 或者使用“.方法名"简写的方式
(. (Date.) getTime) ; <a timestamp>
(.getTime (Date.)) ; 和上面一样哦 ; 使用/ 来调用静态方法
(System/currentTimeMillis) ; <a timestamp> (system is always present) ; 使用 doto 来处理可变的类,所有的函数始终用最初的那个对象值,最后还是返回最初的那个对象 (import java.util.Calendar)
(doto (Calendar/getInstance)
(.set 2000 1 1 0 0 0)
.getTime) ; => A Date. set to 2000-01-01 00:00:00

Ref :http://www.oschina.net/translate/learn-clojure-in-minutes

More : Clojure CLR .

几分钟内学习 Clojure的更多相关文章

  1. 【转】一分钟内检查Linux服务器性能

    近期看了一篇运维排查的问题的十条命令,仔细看了一下,发现就是自己平时经常使用的一些,感觉还不错,就转一发~分享学习~ 如果你的Linux服务器突然负载暴增,告警短信快发爆你的手机,如何在最短时间内找出 ...

  2. 10分钟内基于gpu的目标检测

    10分钟内基于gpu的目标检测 Object Detection on GPUs in 10 Minutes 目标检测仍然是自动驾驶和智能视频分析等应用的主要驱动力.目标检测应用程序需要使用大量数据集 ...

  3. 用十条命令在一分钟内检查Linux服务器性能

    转自:http://www.infoq.com/cn/news/2015/12/linux-performance 如果你的Linux服务器突然负载暴增,告警短信快发爆你的手机,如何在最短时间内找出L ...

  4. 如何在十分钟内插入1亿条记录到Oracle数据库?

    这里提供一种方法,使用 APPEND 提示,使得十分钟内插入上亿数据成为可能. -- Create table create table TMP_TEST_CHAS_LEE ( f01 VARCHAR ...

  5. 1分钟内检查Linux服务器性能的10条命令

    如果你的Linux服务器突然负载暴增,告警短信快发爆你的手机,如何在最短时间内找出Linux性能问题所在?Netflix性能工程团队的Brendan Gregg写下了这篇博文,来看他们是怎样通过十条命 ...

  6. 如何用十条命令在一分钟内检查Linux服务器性能

    “如果你的Linux服务器突然负载暴增,报警短信快发爆你的手机,如何在最短时间内找出Linux性能问题所在?来看Netflix性能工程团队的这篇博文,看它们通过十条命令在一分钟内对机器性能问题进行诊断 ...

  7. django 实现同一个ip十分钟内只能注册一次

    很多小伙伴都会有这样的问题,说一个ip地址十分钟内之内注册一次,用来防止用户来重复注册带来不必要的麻烦 逻辑: 取ip,在数据库找ip是否存在,存在判断当前时间和ip上次访问时间之差,小于600不能注 ...

  8. django 实现同一个ip十分钟内只能注册一次(redis版本)

    上一篇文章,django 实现同一个ip十分钟内只能注册一次 的时候,我们在注册的时候选择使用的使我们的数据库来报错我们的注册的ip信息,可是如果数据量大,用户多的时候,单单靠我们的数据库 来储存我们 ...

  9. 用十条命令在一分钟内检查 Linux 服务器性能

    原文地址: http://www.oschina.net/news/69132/linux-performance 如果你的Linux服务器突然负载暴增,告警短信快发爆你的手机,如何在最短时间内找出L ...

随机推荐

  1. 软工Hello World!团队第二周博客汇总

    2017.10.20-2017.10.26 Scrum会议: 第一天:http://www.cnblogs.com/liusx0303/p/7704482.html 第二天:http://www.cn ...

  2. 欢迎来怼--第二十一次Scrum会议

    一.小组信息 队名:欢迎来怼 小组成员 队长:田继平 成员:李圆圆,葛美义,王伟东,姜珊,邵朔,冉华 小组照片 二.开会信息 时间:2017/11/2 17:05~17:15,总计10min. 地点: ...

  3. YaoLingJump开发者日志(五)V1.0版本完成

    跳跃吧瑶玲下载连接 官网下载 百度网盘下载 提取码:apx9 介绍   总算完成V1.0版本了,下面来简单地介绍一下吧!   打开游戏,最开始会进入到"主界面".   右上角的按钮 ...

  4. 我爱C语言

    各位同志们好,我是来自计算机系的谢畅,我是一个平时看起来高冷其实很逗比的人,我的爱好有很多但只是会一些基础比如游泳,篮球,听听音乐什么的.我的特长是弹吉他虽然弹得不是很溜,我还喜欢朗诵.刚开始我并不是 ...

  5. sublime Remote_encoding cp1252

    "remote_encoding": "cp1252",才能连接远程ftp

  6. timer实现

    实现一个 timer 前段时间写过一篇 blog 谈到 用 timer 驱动游戏 的一个想法.当 timer 被大量使用之后,似乎自己实现一个 timer 比用系统提供的要放心一些.最近在重构以前的代 ...

  7. table中的td限制宽度width也不能让字符过长变成省略号生效?

    table中的td限制宽度width也不能让字符过长变成省略号生效? http://blog.csdn.net/java_mr_zheng/article/details/49423247 CSS t ...

  8. BZOJ 1050 旅行(并查集)

    很好的一道题.. 首先把边权排序.然后枚举最小的边,再依次添加不小于该边的边,直到s和t联通.用并查集维护即可. # include <cstdio> # include <cstr ...

  9. 【题解】CF#983 E-NN country

    首先,我们从 u -> v 有一个明显的贪心,即能向上跳的时候尽量向深度最浅的节点跳.这个我们可以用树上倍增来维护.我们可以认为 u 贪心向上跳后不超过 lca 能跳到 u' 的位置, v 跳到 ...

  10. 【刷题】BZOJ 3510 首都

    Description 在X星球上有N个国家,每个国家占据着X星球的一座城市.由于国家之间是敌对关系,所以不同国家的两个城市是不会有公路相连的. X星球上战乱频发,如果A国打败了B国,那么B国将永远从 ...