1. Forms
Form |
Example(s) |
Boolean |
true,false |
Charactor |
\a |
Keyword |
:tag,:doc |
List |
(1,2,3),(println "foo") |
Map |
{:name “Bill", :age 50} |
Nil |
nil |
Number |
1,4.2 |
Set |
#{:snap :crackle :pop} |
String |
"hello" |
Symbol |
user/foo,java.lang.String |
Vector |
[1 2 3] |
数值类型
42
42
[1 2 3]
[1 2 3]
(+ 1 2)
(3)
(concat [1 2] [3 4])
(1 2 3 4)
(+ 1 2 3 )
(6)
(+)
0
(- 10 5)
5
(* 3 10 10)
300
(> 5 2)
true
(>= 5 5)
true
(< 5 2)
false
(= 5 2)
false
(/ 22 7)
22/7
(class (/ 22 7))
clojure.lang.Ratio
(/ 22.0 7)
3.142857142857143
(quot 22 7)
3
(rem 22 7)
1
(+ 1 (/ 0.0001 1000000000000000000))
1.0
(+ 1 (/ 0.0001M 1000000000000000000)) ;;BigDecimal
1.00000000000000000000001M
(class (* 1000 1000 1000))
java.lang.Integer
(class (* 1000 1000 1000 1000 1000 1000 1000 1000))
java.math.BigInteger
标识符(Symbols)
如:+,concat,java.lang.String 都是symbols
符号名称定义一件事。
1.函数:如str,concat
2.操作符:如+,-
3.命名空间:clojure.core,java.lang
4.数据结构及引用
字符串及字符
"This is a\nmultiple string"
"This is a\nmultiple string"
(println "a\nb\nc")
a
b
c
nil
(.toUpperCase "hello") ;; 这个点说明,是调用的Java 方法,而不是Clojure函数
"HELLO"
(str 1 2 nil 3) ;; str 是toString的Clojure实现。会跳过nil,而不会报错
"123"
字符是 java characters,语法变为\{letter},如\h \hi
(str \h \e \y \space \y \o \u)
"hey you"
(Character/toUpperCase \s)
\S
(interleave "hi" "mix")
\h\m\i\i
(str (interleave "hi" "mix"))
"clojure.lang.LazySeq@627a81b9"
使用apply 函数,来获得字符串.(apply f args* argseq)
(apply str (interleave "hi" "mix"))
"hmii"
(apply str (take-nth 2 "hi mary , where to go"))
"h ay,weet o"
Boolean 和 Nil
(if nil "true" "false");; nil 代表 false
"false"
(if () "We are in Clojure!" "We are in Common Lisp!") ;; List programmers be warned, empty list is true
"We are in Clojure!"
(if 0 "zero is true" "zero is false");; C Programmers be warned:zero is not false in Clojure
"zero is true"
断言函数
(true? expr)
(false? expr)
(nil? expr)
(zero? expr)
(true? true)
true
(true? "foo")
false
(zero? 0.0)
true
(zero? (/ 22 7))
false
Clojure有很多断言,通过(find-doc #"\?$")在REPL中查看
Maps, Keywords, and Structs
(def inventors {"Lisp" "McCarthy" "Clojure" "Hickey"})
#'user/inventors
(def inventors {"Lisp" "McCarthy", "Clojure" "Hickey"})
#'user/inventors
(inventors "Lisp") ;; Maps 是一个函数
"McCarthy"
(get a-map key not-found-val?) ;; 获得Map的Value,如没有此Key,会返回一个自己定义的值。
(get inventors "Lisp" "I dunno!")
"McCarthy"
(get inventors "Foo")
"I dunno!"
Keyword 很像标识符,但需要在标识符前面加一个“:”,keyword会自己解释自己
:foo
:foo
foo
CompilerException java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(NO_SOURCE_PATH:0)
一般,把keyword做为Map的key
(def inventors {:Lisp "McCarthy" :Clojure "Hickey"})
#'user/inventors
(inventors :Clojure)
"Hickey"
(:Clojure inventors) ;; keyword 是一个函数
"Hickey"
(defstruct name & keys) ;; 一个名称,对应多个keys,即定义keys
(defstruct book :title :author)
#'user/book
(struct name & vals);; map对应的多个值
(def b (struct book "Anathem" "Neal Stephenson"))
{:title "Anathem", :author "Neal Stephenson"}
(struct-map name & inits);;初始化Maps及添加新的key&value对
(struct-map book :copyright 2008 :title "Anathem")
{:title "Anathem", :author nil, :copyright 2008}
2.Reader macros
Reader Macro |
Example(s) |
Anonymous function |
#(.toUpperCase %) |
Comment |
;single-line comment |
Deref |
@form=>(deref form) |
Meta |
^form =>(meta form) |
Metadata |
#^metadata form |
Quote |
'form => (quote form) |
Regex pattern |
#"foo" => a java.util.regex.Pattern |
Syntax-quote |
`x |
Unquote |
~ |
Unquote-splicing |
~@ |
Var-quote |
#`x => (var x) |
3.Funcitons
(str "hello" " " "world") ;一个函数仅仅是一个list,第一个元素是函数名
"hello world"
定义函数
(defn name doc-string? attr-map? [params*] body)
(defn greeting
"Returns a greeting of the form 'Hello, username.'"
[username]
(str "Hello, " username))
(greeting "foo")
"Hello, foo"
(greeting)
ArityException Wrong number of args (0) passed to: user$greeting clojure.lang.AFn.throwArity (AFn.java:437)
定义函数,可以有多个body
(defn name doc-string? attr-map? ([params*] body)+ )
(defn greeting
"Returns a greeting of the form 'Hello, username.'
Default username is 'world'."
([] (greeting "world"))
([username] (str "Hello, " username)))
#'user/greeting
(greeting)
"Hello, world"
(defn date [person-1 person-2 & chaperones] ;& arity
(println person-1 "and" person-2
"went out with" (count chaperones) "chaperones." ))
(date "Romeo" "Juliet" "Friar Lawrence" "Nurse")
| Romeo and Juliet went out with 2 chaperones.
1)匿名函数很简单,可以自己解释自己,给一个名字会很难读;
2)匿名函数只需要在内部访问,不需要外部访问;
3)匿名函数需要访问创建他的函数的数据;
(defn indexable-word? [word]
(> (count word) 2))
(use '[clojure.contrib.str-utils :only (re-split)])
(filter indexable-word? (re-split #"\W+" "A fine day it is" ))
-> ("fine" "day" )
(fn [params*] body);匿名函数定义
(filter (fn [w] (> (count w) 2)) (re-split #"\W+" "A fine day"))
("fine" "day")
匿名函数简写:(#body)
参数使用%1,%2,%...
(filter #(> (count %) 2) (re-split #"\W+" "A fine day it is"))
("fine" "day")
(defn indexable-words [text]
(let [indexable-word? (fn [w] (> (count w) 2))]
(filter indexable-word? (re-split #"\W+" text))))
(indexable-words "a fine day it is")
("fine" "day")
返回函数实例
(defn make-greeter [greeting-prefix]
(fn [username] (str greeting-prefix ", " username)))
(defn make-greeter [greeting-prefix]
(fn [username] (str greeting-prefix ", " username)))
(def hello-greeting (make-greeter "Hello"))
#'user/hello-greeting
(def aloha-greeting (make-greeter "Aloha"))
#'user/aloha-greeting
(hello-greeting "world")
"Hello, world"
(aloha-greeting "world")
"Aloha, world"
((make-greeter "Howdy") "pardner")
"Howdy, pardner"
什么时候使用匿名函数
使code可读性好,不会被做为公共的函数调用。建议多多使用匿名函数。
4.Bindings and namespaces
Bindings
(defn triple [number] (* 3 number))
#'user/triple
(triple 10)
30
(defn square-corners [bottom left size]
(let [top (+ bottom size)
right (+ left size)]
[[bottom left] [top left] [top right] [bottom right]]))
#'user/square-corners
(square-corners 10 10 10)
[[10 10] [20 10] [20 20] [10 20]]
(defn greet-author-1 [author]
(println "Hello," (:first-name author)))
(greet-author-1 {:last-name "Vinge" :first-name "Vernor"})
Hello, Vernor
(defn greet-author-2 [{fname :first-name}];argument bind fname to the :first-name
(println "Hello," fname))
(greet-author-2 {:last-name "Vinge" :first-name "Vernor"})
Hello, Vernor
(let [[x y :as coords] [1 2 3 4 5 6]]
(str "x: " x ", y: " y ", total dimensions " (count coords)));:as clause gives you a binding for the entire enclosing structure
"x: 1, y: 2, total dimensions 6"
Namespace
(resolve sym)
(resolve 'foo)
#'user/foo
(in-ns name); 切换Namespace
(String)
java.lang.String
(clojure.core/use 'clojure.core); 导入clojure.core函数
File/separator
java.lang.Exception: No such namespace: File
java.io.File/separator
"/"
(import '(java.io InputStream File));Once you import a class, you can use its short name
(require 'clojure.contrib.math)
(clojure.contrib.math/round 1.7)
2
(round 1.7)
java.lang.Exception:
Unable to resolve symbol: round in this context
(use 'clojure.contrib.math);refer all public vars in clojure.contrib.math
nil
(use '[clojure.contrib.math :only (round)]);:only避免方法冲突
nil
(use :reload '[clojure.contrib.math :only (round)]);包文件有变化时,使用:reload
(use :reload-all 'examples.exploring);
(ns name & references);the ns macro sets the current namespace to name &references 可以是:import,:require,:use
(ns examples.exploring
(:use examples.utils clojure.contrib.str-utils)
(:import (java.io File)))
(find-doc "ns-"); for help
def定义值或名称
(def v1 10)
(def v2 (int 10)); 定义成基本类型,在循环计算中可以提高效率
(def v3 (fn [n] (* n n ))); v3是函数别名
let定义临时变量
局部临时变更定义:
(let [x 10] ( println x))
定义多个变量(def 不能定义多个)
(let [[x y] [3 4]] (println (* x y)));
(let [x 3 y 4 ] (println (* x y )))
(let [[x y] [3 4 5]] [x y]);[3 4]
(let [[_ _ z] [3 4 5]] z); 5
(let [[ a b & c] [1 2 3 4 5]] [a b c]); [1 2 (3 4 5)]
多个变量之间可以依赖(后面的依赖前面的),这点非常非常有用:
(let [x 10 y ( * x x ) z (* 2 y)] (println z)); 200
let 的执行体内可以调用多个函数:
(let [x 10] (println x) (println (* x x )))
binding可以临时改变def定义的变量:
(def v1 10)
(def v2 20)
(binding [v1 1 v2 2] (+ v1 v2));3
(+ v1 v2); 30
(defn f [] (+ v1 v2))
(binding [v1 1 v2 2] (f)); 3
(f); 30
5.Flow control
if,do, and loop/recur
(defn is-small? [number]
(if (< number 100) "yes" ))
(is-small? 50)
"yes"
(is-small? 50000)
nil
(defn is-small? [number]
(if (< number 50) "yes" "no"))
#'user/is-small?
(is-small? 50000)
"no"
(defn is-small? [number]
(if (< number 100)
"yes"
(do
(println "Saw a big number" number)
"no" )))
(is-small? 100)
Saw a big number 100 ; side effect
"no"
(loop [bindings *] exprs*)
(defn testloop []
(loop [result [] x 5]
(if (zero? x)
result
(recur (conj result x) (dec x)))))
#'user/testloop
(testloop)
[5 4 3 2 1]
(defn countdown [result x]
(if (zero? x)
result
(recur (conj result x) (dec x))))
#'user/countdown
(countdown [] 10)
[10 9 8 7 6 5 4 3 2 1]
(into [] (take 5 (iterate dec 5)))
[5 4 3 2 1]
(into [] (drop-last (reverse (range 6))))
[5 4 3 2 1]
(vec (reverse (rest (range 6))))
[5 4 3 2 1]
6.Metadata
metadata是关于数据的数据
(with-meta object metadata)
=======================================================
代码块:do
(do
(println "hi")
(apply * [ 2 3 4 ])
)
hi
24
fn let loop try defn 隐含使用do表达式
定义变量 vars: def
(def p "foo")
其它定义defn defn- defprotocol defonce defmacro deftype defrecord defmethod
local 绑定: let
(defn hypot
[x y]
(let [x2 (* x x)
y2 (* y y)]
(Math/sqrt (+ x2 y2))))
分享到:
相关推荐
### Clojure基础知识与实践应用详解 #### 一、Clojure简介及重要性 **Clojure**是一种基于Java虚拟机(JVM)的现代 Lisp 方言,它不仅继承了 Lisp 家族的强大功能,还充分利用了 JVM 的强大生态。本书《实用 Clojure...
1. **Clojure基础**:本书首先介绍了Clojure的基础知识,包括语言特性、语法结构以及核心库的使用方法。这部分内容为初学者提供了必要的背景知识,同时也适合有经验的程序员作为复习资料。 2. **函数式编程思想**:...
1. **Clojure基础**:Clojure的核心特点是其强大的函数式编程范式,鼓励使用不可变数据结构和高阶函数。了解Clojure的基础语法,如S-expressions(符号表达式)、宏、动态类型以及如何定义和调用函数,是深入研究...
- **Russ Olsen**(Cognitect咨询部副总裁)指出本书非常适合那些已经了解Clojure基础知识但希望更深入理解其应用的人。 - **Chris Houser**(《Joy of Clojure》的合著者)提到了Clojure在Web开发中的灵活性及其对...
Clojure基础 clojure编程语言的语法基础。 如何安装 确保安装了bash,curl,rlwrap和java以下工具。 您可以通过运行以下命令来安装它们: sudo apt install curl rlwrap default-jdk 。 使用以下命令下载clojure...
这本书涵盖了Clojure的基础语法、数据结构、控制流、函数式编程概念以及如何利用Clojure进行系统设计。此外,书中还深入探讨了Clojure的高级特性,如宏、动态绑定以及与Java平台的集成。中文版的《Clojure编程》则为...
1. **基础篇**:这一部分将引导读者入门 Clojure 编程语言的基本概念和语法,为后续深入学习打下坚实的基础。 - **Clojure 入门**:介绍 Clojure 的安装过程、REPL(Read-Eval-Print Loop)环境的使用方法以及简单...
它全面介绍了Clojure的基础知识,包括数据结构、控制流、函数式编程概念、元编程以及与Java的交互。"Programming Clojure_modify.pdf"可能是这本书的一个修改版或更新版本,可能包含了作者的修订或者社区的贡献。 2...
本书详细介绍了如何使用Clojure编写程序,并涵盖了从基础语法到高级主题的各个方面。书中通过丰富的示例代码展示了如何利用Clojure的各种特性来解决实际问题。此外,《Programming Clojure》还讨论了Clojure的开发...
这本书涵盖了从基础语法到高级特性的广泛内容,对于想要学习或提升Clojure技能的程序员来说,是一份宝贵的资源。 首先,Clojure的核心理念是简洁、并发和持久化数据结构。书中详细介绍了Clojure的语法特性,如S...
- **基础语法**:Clojure采用S表达式作为语法结构的基础,所有的代码都是由括号构成的列表。 - **数据类型**:包括但不限于数字、字符串、向量、列表、映射、集等。 - **条件处理**:使用`if`、`cond`等关键字来进行...
《The Joy of Clojure》这本书并非针对初学者的编程指南,而是为那些已经具备一定编程基础(特别是Java或函数式编程语言如Lisp的经验)的程序员提供了一次深入探索Clojure编程语言精髓的机会。本书的核心在于介绍...
这本书由 Carin Meier 撰写,以其简洁明了的阐述方式,为读者提供了深入理解Clojure的基础。 在阅读《Living Clojure》时,你需要重点关注以下几个关键知识点: 1. **Clojure 的基础知识**:Clojure 使用 Lisp 的...
在学习Clojure的过程中,Handbook介绍了语言的基础知识,如REPL(Read-Eval-Print Loop)交互式环境、变量定义、基本类型、类型判断、执行多条语句的do表达式、条件语句、循环语句、正则表达式、命名空间、结构体...