Clojure不支持前向引用

被引用的实体类型Address,GreetResponse:

;; Response types

(defrecord Address [^String street ^String city])

(defrecord GreetResponse [^String person
                          ^String stuff
                          ^long things
                          ^Address address])

如果把实体类定义放到引用这两个类型的代码最后面

(ns org.brinman2002.app.service.SimpleService
  (:import (org.springframework.web.bind.annotation RestController RequestMapping RequestMethod)))

;; Class definition

(gen-class
  :name ^{RestController {} 
          RequestMapping {:value ["simple"]} } org.brinman2002.app.service.SimpleService 
  :methods [[^{RequestMapping {:value ["simple"] :method [RequestMethod/GET]}} greet [] Object ]
            [^{RequestMapping {:value ["simple2"] :method [RequestMethod/GET]}} greet2 [] Object ]
            [^{org.springframework.beans.factory.annotation.Autowired {}} setPlayerRepository [org.brinman2002.app.service.PlayerRepository] void]]
  :state injected
  :init init)



;; Business logic functions

; TODO

;; Class method implementations
(defn -init 
  "Initialize the class by setting the state to an empty map, which can be populated with injected dependencies."
  []
  [[] (atom {})])

(defn -setPlayerRepository
  "Setter for player repository.  This stores the instance in the state of the object."
  [this repo]
  (swap! (.injected this) assoc-in [:player-repo] repo))

(defn -greet
  "Handler for the /simple/simple resource using defrecord."
  [this]
  (GreetResponse. "A test" "of defrecord" 12345 (Address. "123 fake" "Springfield")))
  ;(str "This is a greeting " (:player-repo @(.injected this) )))

(defn -greet2
  "Handler for the /simple/simple2 resource using maps. This actually doesn't seem to work; it throws an ArityException because Spring seems to treat it as a Callable instead of a JSON-able object."
  [this]
  {:test "This is a test" :of "returning raw maps"})


;; Response types

(defrecord Address [^String street ^String city])

(defrecord GreetResponse [^String person
                          ^String stuff
                          ^long things
                          ^Address address])

程序编译将会报错:

Exception in thread "main" java.lang.IllegalArgumentException: Unable to resolve classname: GreetResponse, compiling:(org/brinman2002/app/service/SimpleService.clj:35:3)

这个让人感觉有点不像JVM上的语言风格.无论Java,Scala这种前向引用是支持的.

也就是说,我们需要在引用一个类型之前,先写好类型定义的代码:


(ns org.brinman2002.app.service.SimpleService
  (:import (org.springframework.web.bind.annotation RestController RequestMapping RequestMethod)))

;; Class definition

(gen-class
  :name ^{RestController {} 
          RequestMapping {:value ["simple"]} } org.brinman2002.app.service.SimpleService 
  :methods [[^{RequestMapping {:value ["simple"] :method [RequestMethod/GET]}} greet [] Object ]
            [^{RequestMapping {:value ["simple2"] :method [RequestMethod/GET]}} greet2 [] Object ]
            [^{org.springframework.beans.factory.annotation.Autowired {}} setPlayerRepository [org.brinman2002.app.service.PlayerRepository] void]]
  :state injected
  :init init)



;; Business logic functions

; TODO

;; Class method implementations
(defn -init 
  "Initialize the class by setting the state to an empty map, which can be populated with injected dependencies."
  []
  [[] (atom {})])

(defn -setPlayerRepository
  "Setter for player repository.  This stores the instance in the state of the object."
  [this repo]
  (swap! (.injected this) assoc-in [:player-repo] repo))


;; Response types

(defrecord Address [^String street ^String city])

(defrecord GreetResponse [^String person
                          ^String stuff
                          ^long things
                          ^Address address])

(defn -greet
  "Handler for the /simple/simple resource using defrecord."
  [this]
  (GreetResponse. "A test" "of defrecord" 12345 (Address. "123 fake" "Springfield")))
  ;(str "This is a greeting " (:player-repo @(.injected this) )))

(defn -greet2
  "Handler for the /simple/simple2 resource using maps. This actually doesn't seem to work; it throws an ArityException because Spring seems to treat it as a Callable instead of a JSON-able object."
  [this]
  {:test "This is a test" :of "returning raw maps"})

results matching ""

    No results matching ""