•
->
(-> x & forms)
将forms从头到尾穿成串,具体是将x作为第二个item插入到第一个form中,形成一个表达式,如果有更多form,则将第一个form形成的表达式作为第二个item插入到第二个form中,形成一个表达式,之后再讲第二个form形成的表达式作为第二个item插入到第三个form中,形成一个表达式,以此类推。。。
上面解释的不太清楚。
例子:
user=> (-> "a b c d"
#_=> .toUpperCase
#_=> (.replace "A" "X")
#_=> (.split " ")
#_=> first)
"X“
在该例子中,最终形成:
(first (.split (.replace (.toUpperCase "a b c d") "A" "X") " "))
user=> (first (.split (.replace (.toUpperCase "a b c d") "A" "X") " "))
"X"
通过以上例子好像也不太好解释清楚, 看下下面几个例子:
不传form的情况:
=> (-> "a b c d")
"a b c d"
只传一个form的情况:
=> (-> "a b c d" (println))
a b c d
nil
这个也只传了一个form, 但在这个form中, 我们传了一个参数: "kkkk"
=> (-> "a b c d" (println "kkkk"))
a b c d kkkk
nil
这个也只传了一个form, 但在这个form中, 我们传了一个参数: c
=> (-> [[a b & c] [9 8 7 6 5]] (let c))
(7 6 5)
传了两个form的情况, 第一个form我们传了一个参数: c, 第二个form我们传了一个参数: "kkkk"
=> (-> [[a b & c] [9 8 7 6 5]]
#_=> (let c)
#_=> (println "kkk"))
(7 6 5) kkk
nil
另外一种比较容易和:
(-> x & forms)
混淆的形式是
Positional factory function:
->TypeName
->RecordName
等。
如
->ArrayChunk:
(->ArrayChunk am arr off end)
->ScalaEvalFunction:
(->ScalaEvalFunction script)
;;;; (ns clojure.wf.corex1_1 (import java.util.function.Function) (:require [clojure.wf.core]) (:gen-class)) ;(extend Function { ; apply (fn ; [t] ; (clojure.wf.core/_eval script t))}) (defrecord ScalaEvalFunction [script] Function (apply [this t] (clojure.wf.core/_eval script t)))
(ns clojure.wf.corex1_1test (:require [clojure.test :refer :all] ;[clojure.wf.corex1_1] )) ;; for positional factory function for class:clojure ;; clojure.wf.corex1_1.ScalaEvalFunction ;; (def tfn (->ScalaEvalFunction script)) ;; ;(use '[clojure.wf.corex1_1]) ;; (require 'clojure.wf.corex1_1) (refer 'clojure.wf.corex1_1) ;(refer 'clojure.wf.corex1_1 :only '[ScalaEvalFunction]) (import clojure.wf.corex1_1.ScalaEvalFunction) (deftest ScalaEvalFunctionTest1 (def input "what...") (def script (str "var _input = \"test\"\n" "_input == input")) (def tfn (ScalaEvalFunction. script)) (println "the fn: ", tfn) (testing "[FAIL] it should not be nil." (is (not (nil? tfn)))) ; call fn apply (def result (.apply tfn input)) (println result) (testing "[OK] it's ok." (is (not result)))) ; (deftest ScalaEvalFunctionTest2 (def input "what...") (def script (str "var _input = \"test\"\n" "_input == input")) (def tfn (->ScalaEvalFunction script)) (println "the fn: ", tfn) (testing "[FAIL] it should not be nil." (is (not (nil? tfn)))) ; call fn apply (def result (.apply tfn input)) (println result) (testing "[OK] it's ok." (is (not result))))
>lein test :only clojure.wf.corex1_1test lein test clojure.wf.corex1_1test the fn: #clojure.wf.corex1_1.ScalaEvalFunction{:script var _input = "test" _input == input} log4j:WARN No appenders could be found for logger (com.wf.core.internal.ScalaEngine). log4j:WARN Please initialize the log4j system properly. log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info. input: Object = what... the class of value: java.lang.Boolean false the fn: #clojure.wf.corex1_1.ScalaEvalFunction{:script var _input = "test" _input == input} input: Object = what... the class of value: java.lang.Boolean false Ran 2 tests containing 4 assertions. 0 failures, 0 errors.
这里在使用record的方式可以通过
Positional factory function:
;; for positional factory function for class:clojure ;; clojure.wf.corex1_1.ScalaEvalFunction ;; (def tfn (->ScalaEvalFunction script)) ;; ;(use '[clojure.wf.corex1_1]) ;; (require 'clojure.wf.corex1_1) (refer 'clojure.wf.corex1_1)
(def script (str "var _input = \"test\"\n" "_input == input")) (def tfn (->ScalaEvalFunction script))
(def input "what...") (def result (.apply tfn input))
还可以像使用java那样:
(import clojure.wf.corex1_1.ScalaEvalFunction)
(def script (str "var _input = \"test\"\n" "_input == input")) (def tfn (ScalaEvalFunction. script))
(def input "what...") (def result (.apply tfn input))