1. 在REPL中加载某个文件

      1. (use 'XXX.XXX :reload-all)
    2. defprotocol用于声明协议,extend-protocol用于为不同类型扩展协议

    3. 在ns(命名空间)中,引入clojure模块和Java模块的方式分别为

      1. (:require [clojure.java.io :as io]
      2. [ring.util.codec :refer [assoc-conj]])
      3. )
      4. (:import [java.io PipedInputStream
      5. PipedOutputStream
      6. ByteArrayInputStream
      7. File
      8. Closeable
      9. IOException])


      其中:as为别名,:refer为引用某个/某些方法

    4. defn-用于声明私有函数

    5. 声明重载函数示例:

      1. (defn string-input-stream
      2. "Returns a ByteArrayInputStream for the given String."
      3. {:added "1.1"}
      4. ([^String s]
      5. (ByteArrayInputStream. (.getBytes s)))
      6. ([^String s ^String encoding]
      7. (ByteArrayInputStream. (.getBytes s encoding))))
    6. -> ->> doto as->的区别

    1)->串联一组函数,将每一个函数的返回值作为下一个函数的第一个参数

    1. (-> (.lastModified file)
    2. (/ 1000) (long) (* 1000)
    3. (java.util.Date.))

    2)->> 串联一组函数,将每一个函数的返回值作为下一个函数的最后一个参数
    3)doto后第一个参数将作为后续所有函数的第一个参数及返回值
    4)as-> 将第一个参数用第二个参数的符号表示,后续该符号变为每个函数的返回值

    1. (as-> 5 $
    2. (* 4 $)
    3. (- 14 $)
    4. (/ $ 2))
    1. try-catch-finally示例:

      1. (try
      2. (.close ^java.io.Closeable stream)
      3. (catch IOException _ nil)
      4. (finally (.close stream))))
    2. proxy用于实现java的一个接口,类似于java中的匿名内部类,示例:

      1. (defn- ^AbstractHandler proxy-handler [handler]
      2. (proxy [AbstractHandler] []
      3. (handle [_ ^Request base-request ^HttpServletRequest request response]
      4. (when-not (= (.getDispatcherType request) DispatcherType/ERROR)
      5. (let [request-map (servlet/build-request-map request)
      6. response-map (handler request-map)]
      7. (servlet/update-servlet-response response response-map)
      8. (.setHandled base-request true))))))
    3. 利用reduce和assoc将request中所有参数加入到map中

      1. (defn- get-headers
      2. "Creates a name/value map of all the request headers."
      3. [^HttpServletRequest request]
      4. (reduce
      5. (fn [headers, ^String name]
      6. (assoc headers
      7. (.toLowerCase name Locale/ENGLISH)
      8. (->> (.getHeaders request name)
      9. (enumeration-seq)
      10. (string/join ","))))
      11. {}
      12. (enumeration-seq (.getHeaderNames request))))
    4. 解构map中的值:
      let [{:keys [status headers body]} response-map]
      函数式编程和数据建模已经给了我们很强的表达力,并且使得我们可以把代码里面的重复模式抽象出来。宏应该被当做我们的终极武器,用它来简化控制流,添加一些语法糖以消除重复代码以及一些难看的代码。

    5. 使用file-seq来实现文件夹的遍历。
    6. 使用(seq coll)来判断一个集合非空,不要用(not (empty? coll))
    7. 当不想让结果为惰性集合时,使用mapv、filterv这类的函数代替map和filter。
    8. 将字符序列转成字符串:(apply str coll)。
    9. 将二元vector的序列转成map: (into {} coll)。
    10. 按数量快速分组使用partition,如(partition 5 coll)即为5个一组。
    11. 可以将中间结果写在临时文件中,这样可以清晰地看到代码执行的过程。
    12. 如果需要一个函数,不管参数是什么,返回结果都一样,用constantly: (constantly x),返回值是一个函数。
    13. 如果需要一个函数,返回参数本身,用identity: (identity x),返回值是x。
    14. 将map后的结果连接到一块用mapcat,(mapcat f coll)相当于(apply concat (map f coll))。
    15. 取多元序列中的数据可以用get-in: (get-in m ks),更新数据可以用update-in: (update-in m ks f)。
    16. defmulti和defmethod配合使用,可以定义多重方法,用于处理不同类型的参数。如: ```java ;this example illustrates that the dispatch type ;does not have to be a symbol, but can be anything (in this case, it’s a string)

    (defmulti greeting (fn[x] (get x “language”)))

    ;params is not used, so we could have used [_] (defmethod greeting “English” [params] “Hello!”)

    (defmethod greeting “French” [params] “Bonjour!”)

    ;;default handling (defmethod greeting :default [params] (throw (IllegalArgumentException. (str “I don’t know the “ (get params “language”) “ language”))))

    ;then can use this like this: (def english-map {“id” “1”, “language” “English”}) (def french-map {“id” “2”, “language” “French”}) (def spanish-map {“id” “3”, “language” “Spanish”})

    =>(greeting english-map) “Hello!” =>(greeting french-map) “Bonjour!” =>(greeting spanish-map) java.lang.IllegalArgumentException: I don’t know the Spanish language

    1. 23. 常用变量命名
    2. rdr -> reader<br />hdr -> header<br />c -> char<br />coll -> collection
    3. 24. 对于互相引用的函数,可以在上方使用declare先进行声明,如:
    4. ```javascript
    5. ;; Ahead decl because some fns call into each other.
    6. (declare parse parse-input parse-file tag-content)