多分あなたはレコードを探していますか?
(require '[clojure.set :as cset])
(defrecord Person [name age address phone email])
;; Make a keyword-based constructor to verify
;; args and decouple ordering.
(let [valid #{:name :age :address :phone :email}]
(defn mk-person[& args]
(let [h (apply hash-map args)
invalid (cset/difference (set (keys h)) valid)]
(when-not (empty? invalid)
(throw (IllegalArgumentException. (pr-str invalid))))
; any other argument validation you want here
(Person.
(:name h) (:age h) (:address h) (:phone h) (:email h)))))
=> (def p (mk-person :name "John" :email "[email protected]"))
#:user.Person{:name "John", :age nil, :address nil, :phone nil,
:email "[email protected]"}
今あなたが機能(例外)やキーワード(ない例外)を使用してデータにアクセスすることにより、入力ミスの名前の例外をしたいかどうかを選択することができます。
=> (.fax p)
java.lang.IllegalArgumentException:
No matching field found: fax for class user.Person
=> (:fax p)
nil
このアプローチでは、既存のメソッドと競合するフィールド名を避ける必要があります。 (@Jouniからのコメントを参照してください。)また
、あなたは検索用キーワードや無効なキーをチェックアクセサ関数で使用して、フィールド名の制限を回避することができます
(defn get-value [k rec]
(let [v (k rec ::not-found)]
(if (= v ::not-found)
(throw (IllegalArgumentException. (pr-str k)))
v)))
=> (get-value :name p)
"John"
=> (get-value :fax p)
IllegalArgumentException: :fax
を「間違っている非構造リストの一部 "タイプの問題は、リスト内の"人 "のようなものをエンコードしようとしたことから来るかもしれません。 「郵便番号は「人」リストの3番目の「アドレス」リストの4番目の要素です」というようなことを覚えておく必要があります。
'classical' Lispでは、アクセサ関数を書くことで解決できるかもしれませんが、Clojureではレコードを使用するかもしれません。
Typosはどのプログラミング言語でも問題を引き起こします。できるだけ早くキャッチしようとするとよいでしょう。
オートコンプリート機能を備えたJava IDEは、入力中にいくつかのタイプミスを犯す可能性があり、コンパイル時に静的型付けされた言語が多くのものをキャッチしますが、動的言語では実行時まで見つけられません。これは動的言語(Python、Rubyなど)の欠点だと考えている人もいますが、その人気から、プログラマーは、IDEの自動補完やコンパイル時のエラーの損失よりも、得られる柔軟性と保存されたコードが重要だと考えています。
どちらの場合も原則は同じです:原因を見つけるために必要なコードが少なくて済むため、以前の例外は優れています。理想的には、スタックトレースはあなたを誤植にまっすぐに導くだろう。 Clojureでは、レコードとアクセサ関数がそれを提供します。
これが掲載されて以来、core.typedがリリースされ、同じことをhttp://typedclojure.org/でも行うことができます – Ben