在clojure中对deftype'd对象有什么好的toString方法

Nic*_*ton 6 clojure instantiation tostring deftype

(deftype Bag [state]
   Object
     (toString [bag]
       (str "Bag???" state)))
Run Code Online (Sandbox Code Playgroud)

我希望toString看起来像

clojure.core=> (def b (Bag. {:apples 1 :bannanas 4}))
#'clojure.core/b
clojure.core=> (str b)
"BAG: {:apples 1 :bannanas 4}"
Run Code Online (Sandbox Code Playgroud)

什么是表达信息的好方法?是

"Bag/{:k :v}" 
Run Code Online (Sandbox Code Playgroud)

更好?社区如何称呼您的toStrings?

Ale*_*art 8

根据您正在尝试做的事情,最简单的方法是使用defrecord:

user=> (defrecord Bag [state])
user.Bag
user=> (def b (Bag. :foo))
#'user/b
user=> b
#:user.Bag{:state :foo}

虽然你上面看到的是pr,但不是str:

user=> (str b)
"user.Bag@53e935f4"
user=> (prn b)
#:user.Bag{:state :foo}
nil

所以我们只做一个改变:

user=> (defrecord Bag [state]
         Object
         (toString [bag] (pr-str bag)))
user.Bag
user=> (def b (Bag. :foo))
#'user/b
user=> (str b)
"#:user.Bag{:state :foo}"
user=> (.toString b)
"#:user.Bag{:state :foo}"

现在,如果以上不适合,那么下一个选项是向print-method多方法添加新方法.谷歌周围的细节.

除此之外:除非你做的事情非常低defrecord,deftype否则通常应优先使用.


Ale*_*art 5

以下是deftype.

user=> (deftype Bag [state] 
         Object 
         (toString [_] 
           (str "BAG: " (pr-str state))))
user.Bag
user=> (def b (Bag. {:apples 1 :bannanas 4}))
#'user/b
user=> (str b)
"BAG: {:bannanas 4, :apples 1}"
Run Code Online (Sandbox Code Playgroud)