10

JavaScript 関数の引数値と同様に、関数に渡される実際の値のシーケンスを取得できるものが必要です。

を使用して関数の引数リスト全体を取得できることを認識しています

(defn fx [& args]
 args)

<= (fx {:a 1} 2)
=> ({:a 1} 2)

しかし、これは私の機能のアリティを取り除きます。のようなものが欲しい

(defn fx [{:keys [a]} b]
 (MAGIC_FUNCTION_THAT_RETURNS_THE_ARGS_VALUES))

<= (fx {:a 1} 2)
=> ({:a 1} 2)

関数に渡された値の生のシーケンスを取得することは可能ですか?

4

6 に答える 6

4

関数本体が実行されるまでに、パラメーターは既に分解されています。独自のdefnマクロを定義して、それらの値を公開できます。Lighttable が引数の値を表示するために Instarepl でこれを行っていることは知っています。

于 2013-09-14T03:45:22.467 に答える
3

引数の破棄を使用すると役立ちます。以下は私にとってはうまく機能します(私の知る限り、古いバージョンのclojureでも機能します)。

(defn example [ & [a b :as args]] [a b args])
(example 1 2) 
 => [1 2 (1 2)]

重要な点は、 の後に引数を破棄できることです&。欠点は、予想よりも多くの引数で関数を呼び出すことができることです (たとえば(example 1 2 3)、有効な呼び出しです。これが問題になる可能性がある場合は、特別な注意を払う必要があります。

注:同様の機能を探しているときに、この質問に出くわしました。ここからアイデアを掘り下げて使用し続け、この回答で:as提案されているように、問題の解決策を見つけました。

于 2015-07-29T12:13:56.307 に答える
1

パラメータをベクトルとして渡す必要があるため、あまり良くありませんが、適切なようです

user.main=> (defn fx [[{:keys [a] :as e} b :as o]] [a b e o])
#'user.main/fx
user.main=> (fx [{:a 1} 2])
[1 2 {:a 1} [{:a 1} 2]]
user.main=> 
于 2013-09-14T03:22:10.763 に答える
0

これは私が調理できる最高のものです。

(def ^:dynamic *arguments* nil)

(defn unstructure [form]
  (cond
   (or (vector? form) (map? form)) (gensym)
   (= form '&) '&
   :else form))

(defmacro bind-args-defn [name args & body]
  (let [simple-args (vec (map unstructure args))
        i (.lastIndexOf simple-args '&)
        [h r] (split-at (if (neg? i) (count simple-args) i) simple-args)
        r (drop 1 r)]
    `(defn ~name
       ~simple-args
       (binding [*arguments* (lazy-cat ~@(map vector h) ~@r)]
         (let [~args *arguments*]
           ~@body)))))

(bind-args-defn                            ;;my special val binding defn
 silly                                     ;;the name
 [{:keys [a]} [b & c] & d]                 ;;the arg vector
 {:vals *arguments* :a a :b b :c c :d d})  ;;the body

明らかに、これは defn に渡すことができる defn オプション (メタデータ、docstring、pre および post、arities など) の完全なセットを受け入れませんが、アイデアを示していると思います。

ベクトルをキャプチャし、元のベクトルと同じ長さのベクトルをargs作成することで機能しますが、構造化は行われません。それを引数ベクトルとして使用します。次に、このベクトルを のないフラットなベクトルに変換し、これを に割り当てます。その後、元のベクトルを使用して分解されます。ちょっと複雑ですが、現時点で私が望むことはできます。simple-argsargsdefnsimple-args&*arguments**arguments*args

> (silly {:a 1} [2 3 4] 5 6)
  {:vals ({:a 1} [2 3 4] 5 6), :a 1, :b 2, :c (3 4), :d (5 6)}
于 2013-09-15T05:19:16.313 に答える