•
reify
(reify &
opts+specs)
reify
是一个宏,结构如下:
(reify options* specs*)
目前没有说明
options
,不需要指定。每个
specs
由协议或接口名及后跟的
0
个或多个方法体组成:
protocol-or-interface-or-Object
(methodName [args+] body)*
如果是协议或接口,需要提供所有的方法实现。如果是对象,还可以覆盖对象中的方法。需要说明的是,
方法的第一个参数必须指定相应的目标对象,在
Java
语言中,就是
“
this
”
。
例子:
user=> (str (let [f "foo"]
#_=> (reify Object
#_=> (toString [this] f))))
"foo"
user=> (seq (let [f "foo"]
#_=> (reify clojure.lang.Seqable
#_=> (seq [this] (seq f)))))
(\f \o \o)
再来一个例子:
user=> (def server (reify
#_=> Server
#_=> (server-init [this]
#_=> (str "server init"))
#_=> (server-start [this]
#_=> (str "server start"))))
#'user/server
user=> (.server-init server)
"server init"
user=> (.server-start server)
"server start"
再来一个例子:
user=> (def def-fp (reify
#_=> Server
#_=> (server-init [this]
#_=> (str "server init"))
#_=> (server-start [this]
#_=> (str "server start"))
#_=> Client
#_=> (client-init [this]
#_=> (str "client init"))
#_=> (client-start [this]
#_=> (str "client start"))))
#'user/def-fp
user=> (class def-fp)
user$reify__1440
user=> (.server-init def-fp)
"server init"
user=> (.server-start def-fp)
"server start"
user=> (.client-init def-fp)
"client init"
user=> (.client-start def-fp)
"client start"
一个实际的例子:

<!--[if ppt]-->
•<!--[endif]-->
<!--[if ppt]-->
•<!--[endif]-->
defprotocol
core.clj:
;;;; (ns clojure.wf.core (import java.util.function.Function) (:gen-class)) ;;; control flow ;;; @see com.wf.core.AbstractControlFlow (defprotocol AbstractControlFlow ;; (getFunctionExpress [this]))
TestFunction.java
import java.util.function.Function;
public class TestFunction implements Function<String, String> {
public TestFunction() {
System.out.println("test function");
}
public String apply(String s) {
System.out.println(s);
return s;
}
}
(ns clojure.wf.test (import java.util.function.Function) (import com.wf.core.TestFunction) (:require [clojure.test :refer :all] [clojure.wf.core])) ;;; (deftype AControlFlow [^Function functionExpress] clojure.wf.core/AbstractControlFlow (getFunctionExpress [this] functionExpress)) (deftest getFunctionExpressTest (println "testing clojure.wf.core.AControlFlow/getFunctionExpress[_]") (comment " testing clojure.wf.core.AControlFlow/getFunctionExpress[_] ... ") ; (def tfn (TestFunction.)) ; (def a (AControlFlow. tfn)) ; call fn getFunctionExpress (def functionExpress (.getFunctionExpress a)) ; call fn apply (def result (.apply functionExpress "what...")) (println result))
>lein test :only clojure.wf.test/getFunctionExpressTest lein test clojure.wf.test testing clojure.wf.core.AControlFlow/getFunctionExpress[_] test function what... what... Ran 1 tests containing 0 assertions. 0 failures, 0 errors.
defprotocol 在定义方法的时候不能指定参数和返回类型。这在编译成java后全部映射为Object。
definterface
corex.clj
;;;; (ns clojure.wf.corex (import java.util.function.Function) (:gen-class)) (definterface AbstractControlFlow ;; function express (^java.util.function.Function getFunctionExpress []))
TestFunction.java
import java.util.function.Function;
public class TestFunction implements Function<String, String> {
public TestFunction() {
System.out.println("test function");
}
public String apply(String s) {
System.out.println(s);
return s;
}
}
corextest.clj
(ns clojure.wf.corextest (import java.util.function.Function) (import com.wf.core.TestFunction) (:require [clojure.test :refer :all] [clojure.wf.corex])) ;;; (deftype AControlFlow [functionExpress] clojure.wf.corex.AbstractControlFlow (^Function getFunctionExpress [this] (println "fn getFunctionExpress called...") functionExpress)) (deftest getFunctionExpressTest (println "testing getFunctionExpress") (comment " testing getFunctionExpress ... ") ; (def tfn (TestFunction.)) ; (def a (AControlFlow. tfn)) ; call fn getFunctionExpress (def functionExpress (.getFunctionExpress a)) ; call fn apply (def result (.apply functionExpress "what...")) (println result))
>lein test :only clojure.wf.corextest/getFunctionExpressTest lein test clojure.wf.corextest testing getFunctionExpress test function fn getFunctionExpress called... what... what... Ran 1 tests containing 0 assertions. 0 failures, 0 errors.