`

Clojure 基础

 
阅读更多

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"))

   #'user/b

b
   {:title "Anathem", :author "Neal Stephenson"}

(:title b)
   "Anathem"

(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.


Anonymous Functions
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

(let [bindings*] exprs*)
(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]]

Destructuring
(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

(in-ns 'myapp)

(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"

Recur with loop/recur
(loop [bindings *] exprs*)

(recur 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))))


 

 

分享到:
评论

相关推荐

    practical clojure

    ### Clojure基础知识与实践应用详解 #### 一、Clojure简介及重要性 **Clojure**是一种基于Java虚拟机(JVM)的现代 Lisp 方言,它不仅继承了 Lisp 家族的强大功能,还充分利用了 JVM 的强大生态。本书《实用 Clojure...

    The Joy of Clojure, 2nd Edition

    1. **Clojure基础**:本书首先介绍了Clojure的基础知识,包括语言特性、语法结构以及核心库的使用方法。这部分内容为初学者提供了必要的背景知识,同时也适合有经验的程序员作为复习资料。 2. **函数式编程思想**:...

    clojure-must-watch-源码.rar

    1. **Clojure基础**:Clojure的核心特点是其强大的函数式编程范式,鼓励使用不可变数据结构和高阶函数。了解Clojure的基础语法,如S-expressions(符号表达式)、宏、动态类型以及如何定义和调用函数,是深入研究...

    Pragmatic - Web.Development.with.Clojure.Jan.2014.pdf

    - **Russ Olsen**(Cognitect咨询部副总裁)指出本书非常适合那些已经了解Clojure基础知识但希望更深入理解其应用的人。 - **Chris Houser**(《Joy of Clojure》的合著者)提到了Clojure在Web开发中的灵活性及其对...

    clojure-basics:Clojure编程语言的语法基础

    Clojure基础 clojure编程语言的语法基础。 如何安装 确保安装了bash,curl,rlwrap和java以下工具。 您可以通过运行以下命令来安装它们: sudo apt install curl rlwrap default-jdk 。 使用以下命令下载clojure...

    clojure电子书

    这本书涵盖了Clojure的基础语法、数据结构、控制流、函数式编程概念以及如何利用Clojure进行系统设计。此外,书中还深入探讨了Clojure的高级特性,如宏、动态绑定以及与Java平台的集成。中文版的《Clojure编程》则为...

    Clojure Data Analysis Cookbook

    1. **基础篇**:这一部分将引导读者入门 Clojure 编程语言的基本概念和语法,为后续深入学习打下坚实的基础。 - **Clojure 入门**:介绍 Clojure 的安装过程、REPL(Read-Eval-Print Loop)环境的使用方法以及简单...

    clojure1.3.0及资料

    它全面介绍了Clojure的基础知识,包括数据结构、控制流、函数式编程概念、元编程以及与Java的交互。"Programming Clojure_modify.pdf"可能是这本书的一个修改版或更新版本,可能包含了作者的修订或者社区的贡献。 2...

    Programming Clojure 英文电子版

    本书详细介绍了如何使用Clojure编写程序,并涵盖了从基础语法到高级主题的各个方面。书中通过丰富的示例代码展示了如何利用Clojure的各种特性来解决实际问题。此外,《Programming Clojure》还讨论了Clojure的开发...

    programming-clojure-3rd

    这本书涵盖了从基础语法到高级特性的广泛内容,对于想要学习或提升Clojure技能的程序员来说,是一份宝贵的资源。 首先,Clojure的核心理念是简洁、并发和持久化数据结构。书中详细介绍了Clojure的语法特性,如S...

    Clojure入门教程.pdf

    - **基础语法**:Clojure采用S表达式作为语法结构的基础,所有的代码都是由括号构成的列表。 - **数据类型**:包括但不限于数字、字符串、向量、列表、映射、集等。 - **条件处理**:使用`if`、`cond`等关键字来进行...

    the joy of clojure.pdf

    《The Joy of Clojure》这本书并非针对初学者的编程指南,而是为那些已经具备一定编程基础(特别是Java或函数式编程语言如Lisp的经验)的程序员提供了一次深入探索Clojure编程语言精髓的机会。本书的核心在于介绍...

    living clojure pdf epub azw3

    这本书由 Carin Meier 撰写,以其简洁明了的阐述方式,为读者提供了深入理解Clojure的基础。 在阅读《Living Clojure》时,你需要重点关注以下几个关键知识点: 1. **Clojure 的基础知识**:Clojure 使用 Lisp 的...

    Clojure Handbook(2012.11.1)

    在学习Clojure的过程中,Handbook介绍了语言的基础知识,如REPL(Read-Eval-Print Loop)交互式环境、变量定义、基本类型、类型判断、执行多条语句的do表达式、条件语句、循环语句、正则表达式、命名空间、结构体...

Global site tag (gtag.js) - Google Analytics