そこで、def の「name」部分に関数を渡したいと思います。問題は次のとおりです。「def の最初の引数はシンボルでなければなりません」
私は例えばやろうとしています:
(def serverNumber 5)
(def (str "server" serverNumber) {:id serverNumber :value 4939})
しかし、これを行う方法がわかりません。どんな助けでも大歓迎です:)
そこで、def の「name」部分に関数を渡したいと思います。問題は次のとおりです。「def の最初の引数はシンボルでなければなりません」
私は例えばやろうとしています:
(def serverNumber 5)
(def (str "server" serverNumber) {:id serverNumber :value 4939})
しかし、これを行う方法がわかりません。どんな助けでも大歓迎です:)
まず、これは悪い考えのように思われることに注意する必要があります。def
動的に生成された名前で sを生成しようとしているのはなぜですか? (@pst が既に指摘したように、マップは、動的に生成された識別子を使用してバインディングを作成するための通常のソリューションです。)
これを行う正当な理由があると仮定すると (ユーザーの定義を生成するライブラリ機能の一部である可能性があります)、マクロを使用してこれを実現できます。
(defmacro def' [sym-exp & other-args]
`(def ~(-> sym-exp eval symbol) ~@other-args))
(def serverNumber 5)
(def' (str "server" serverNumber) {:id serverNumber :value 4939})
これはトップレベルでのみ機能することに注意してください (マクロはコンパイル時に実行されるため)。関数などでこれを行いたい場合は、eval を使用するだけです。
(defn def'' [sym-exp & other-args]
(eval `(def ~(-> sym-exp eval symbol) ~@other-args)))
たくさんのエージェントを作成したいだけなら、おそらく次のようなものがうまくいくでしょう:
(def servers
(vec (for [i (range 5)]
{:id i :value 4939})))
次に、インデックスでそれらにアクセスできます。
(servers 0)
; => {:id 0, :value 4939}
と同等の実行時def
は次のintern
とおりです。
(intern *ns*
(symbol (str "server" server-number))
{:id server-number :value 4939})