2010-09-10 4 views
5
(deftype Bag [state] 
    Object 
    (toString [bag] 
     (str "Bag???" state))) 

Я хочу ToString, чтобы выглядеть какЧто такое хороший метод ToString для объекта deftype'd в Clojure

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

Что такое хороший clojurey способ представления этой информации? Факс:

"Bag/{:k :v}" 

лучше? Как сообщество вы называете своим toStrings?

ответ

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}" 
6

В зависимости от того, что вы пытаетесь сделать, самый простой способ заключается в использовании 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) 
"[email protected]" 
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. Об этом Google.

Помимо этого, следует использовать defrecord по сравнению с deftype, если вы не делаете что-то очень низкоуровневое.

+0

Определить низкий уровень. Я пытаюсь создать новые типы коллекций (сумки и мультимаксы). Когда вы используете defrecord или deftype и почему? –

+0

Используя этот метод с помощью deftype, вы получаете java.lang.StackOverflowError –

+0

Да, если вы создаете новый тип коллекции, то, вероятно, неверный тип ошибки, в то время как defrecord более уместен при необходимости что-то вроде структуры некоторых данных домена. –

Смежные вопросы