It is not difficult to understand the VaR, ref, agent, and atom provided by colure. The key is that you do not know where to use them?
With the increase in the number of clojure codes, we have a better understanding of var. Next we will share with you that it will be a pleasure to help you understand var more quickly.
Java variables are real variables. You can change them at any time and change them according to your thinking. You don't even pay attention to them. But clolure remains unchanged, and its var needs to be well considered.
1. Generate VaR
(Def x 5) (println X) -------------> 5; A Var is generated. Note that X in (println X) is parsed into its value in the environment, that is, 5, but var itself is also an object. If you want to get var itself, you need to use: # 'x, but what is the purpose? Some special forms or macro are required. For example: (Var-set X 6) If you use VaR-set for the first time, it is very likely to be written like this, but it is actually incorrect. The correct one is: (Var-set # 'x 6). This is correct, but it is still wrong to combine with the above Code. The error prompt will be: Java. lang. illegalstateexception: Can't change/establish root binding of: X with set.
2. Change the value of var.
(DEF ^: dynamic X 5) (binding [x 6] (Var-set (var x) 8); (var x) and # 'x equivalent X) ---------> 8; the condition for modifying var must be declared as dynamic and must be in binding.
3. Changing VaR is so troublesome, and the sample code of 2 is meaningless. What is the purpose?
(def ^:dynamic *shiro-respnse*)(deftest cssesion-request (binding [*shiro-respnse* ((csession-app) (sample-request))] (is (get-in *shiro-respnse* [:cookies :JSESSIONID]))))
Clojure's macro: With-precision is an example. But the best way to understand VaR is:You think that you must use VaR for a piece of code, otherwise the code will be very uncomfortable.
At that time, your understanding of VaR will make essential improvements.
Since clojure only has one test: Is. The result used to test the form following is true. In code 3 above, to test whether the response returned by the csession-app contains the JSESSIONID, if binding is not required, the form after is will be very long and multiple is must be connected by do. After binding is used, the code is much refreshed.
However, the use of binding does not actually reflect the role of binding, and can be replaced by let.
I used binding because I finally found a chance to use binding in my own code and it works.
4. Use variable VAR to write clojure code. (This is actually the anti-clojure mode)
(Defn factorial [x] (with-local-vars [ACC 1, CNT x] (while (> @ CNT 0) (Var-set ACC (* @ ACC @ CNT )) (Var-set CNT (Dec @ CNT) @ ACC). This code is easy for Java programmers to understand.
5. the real use of VaR is from the source code of clojure.
(defmacro with-precision "Sets the precision and rounding mode to be used for BigDecimal operations. Usage: (with-precision 10 (/ 1M 3)) or: (with-precision 10 :rounding HALF_DOWN (/ 1M 3)) The rounding mode is one of CEILING, FLOOR, HALF_UP, HALF_DOWN, HALF_EVEN, UP, DOWN and UNNECESSARY; it defaults to HALF_UP." {:added "1.0"} [precision & exprs] (let [[body rm] (if (= (first exprs) :rounding) [(next (next exprs)) `((. java.math.RoundingMode ~(second exprs)))] [exprs nil])] `(binding [*math-context* (java.math.MathContext. ~precision [email protected])] [email protected])))
This is a macro, and the code can be correctly executed by binding the environment. So why not use let here? You can use * match-context * in the body you input, and the * match-context * is the VaR of Thread Local, you can use this code without interfering with the * match-context * value of the other code.
About the VaR of clojure, I know about 70%.