7

別の構造体をベースとして新しいベースを作成する関数を作成しようとしています。最初に、古い構造体と同じフィールドを持つ新しい構造体を作成するマクロを作成しようとしました。私がこれを行うべきだと思ったマクロは以下のとおりですが、次のエラーが発生します。

java.lang.Exception: Can't use qualified name as parameter: user/p1__132 

大きい:

(defmacro prototype [structure obj]
  `(apply struct ~structure (map #(~obj %) (keys ~obj))))

使用例:

(defstruct bintree :data :left :right)
(def a (struct bintree 3))
(prototype bintree a)

この場合の望ましい出力は次のようになります。

{:data 3 :left nil :right nil}
4

3 に答える 3

8

あなたの質問へのコメントとして投稿されたリンクセスには答えが含まれています(犯人は無名関数への引数が処理される方法です)。gensym引数を使用すると、次のように機能するはずです。

(defmacro prototype [structure obj]
  `(apply struct ~structure (map (fn [x#] (~obj x#)) (keys ~obj))))
于 2009-07-06T23:29:41.580 に答える
3

修正されたバージョンは次のとおりです。

(defmacro prototype [structure obj]
  `(apply struct ~structure (map ~obj (keys ~obj))))

なぜこれがマクロである必要があるのですか?関数も機能します:

(defn prototype [structure obj]
  (apply struct structure (map obj (keys obj))))

なぜ構造をコピーしたいのですか?構造は不変であるため、それらをコピーすることは役に立ちません。この関数は、上記の関数と同じことを行います。

(defn prototype [structure obj] obj)

追加のキーと値を使用して新しい構造を作成する場合は、を使用しますassoc

于 2009-07-06T23:27:11.930 に答える
2

#()マクロ内で使用しないでください。

ユーザー>(macroexpand-1 `(foo#(bar%)baz))
(user / foo(fn * [user / p1__2047](user / bar user / p1__2047))user / baz)

fn*フォームのパラメータリストに名前空間修飾記号が含まれているわけではありません。それはあなたが得ているエラーです。マクロではこの種の特別なリーダー構文を避け、代わりに長い形式を使用する必要があります。

于 2009-07-06T23:31:44.307 に答える