1

2つの文字列を受け入れるマクロを作成しようとしています。1つは正規表現パターンで、もう1つはテスト用の文字列です。いくつかの読み取り(このあたりを含む)から、# ""として表示されるのは、私が使用して試したリーダーマクロですre-patternが、実行時に次のように失敗するようです。

スレッド"main"の例外java.lang.ClassCastException:clojure.lang.Symbolをjava.lang.CharSequenceにキャストできません

私のコード:

(defmacro checkre [ strre strstring ] 
  (re-find (re-pattern strre) strstring))

呼び出し例:

(defn hasthing [xp]
  (checkre "(?i)^.*blabla" xp))

ありがとう!

4

2 に答える 2

4

あなたは近くにいます。しかし、これにはマクロは必要ありません (おそらく使用すべきではありません):

(defn checkre [ strre strstring ] 
  (re-find (re-pattern strre) strstring))
(defn hasthing [xp]
  (checkre "(?i)^.*blabla" xp))
(hasthing "stuff blabla")
;=> "stuff blabla"

マクロは必要な場合にのみ使用するのが最適です。マクロは関数ほど簡単に構成できず、推論するのが難しいからです (マクロ展開フェーズのため)。

マクロ バージョンが失敗する理由は、それらが文字列ではなくシンボルである場合に、マクロの展開時にバインドしようstrreとしているからです。strstring機能する(少し倒錯した)マクロバージョンは次のとおりです。

(defmacro checkre [ strre strstring ] 
  `(re-find ~(re-pattern strre) ~strstring))
(defn hasthing [xp]
  (checkre "(?i)^.*blabla" xp))
(hasthing "stuff blabla")
;=> "stuff blabla"
于 2013-01-28T19:58:13.227 に答える
1

なぜこれをマクロにするのですか?関数にするだけでうまくいきます。

=> (defn checkre 
     [strre strstring] 
     (re-find (re-pattern strre) strstring))
#'user/checkre
=> (checkre "[aeiou]" "Hello")
"e"

正規表現をバインドする関数を作成する場合は、関数が関数を返すようにします

=> (defn checkre 
     [strre] 
     (fn [strstring] (re-find (re-pattern strre) strstring)))
=> (def hasthing (checkre "[aeiou]"))
=> (hasthing "Hello")
"e"
于 2013-01-28T19:58:02.863 に答える