=wxیدگاه خود را در جایگاه نظرسنجی حالت Clojure 2024 به اشتراک بگذارید!

خوش آمدید!

لطفاً برای اطلاعات بیشتری در مورد نحوه کارکرد این صفحه به درباره مراجعه کنید.

0 رای
درcore.async به وسیله
(case-let) یک مکرو برای مدیریت پیام‌هایی از فرم {{[:message-tag, arg1, arg2, ...]}} با متغیرهای محلی به عنوان متغیرهای گیرنده است. وقتی در یک block go استفاده شود، به درستی کار نمی‌کند. توجه داشته باشید که یک مکرو ساده با case، مانند (defmacro my-case [expr & cases] `(case ~expr ~@cases)) به درستی کار می‌کند.

(پروژه نمونه پیوست شده)

(case-let) تعریف


(ns core-async-bug.macros)

(defmacro case-let [expr & cases]
  (let [msg (gensym)]
    `(let [~msg ~expr]
       (case (first ~msg)
        ~@(apply concat (for [[key [args & body]] (partition 2 cases)]
                    [key `(let [~args (rest ~msg)] ~@body)]))))))


کد تست ClojureScript


(ns core-async-bug.core
  (:require-macros [cljs.core.async.macros :refer [go]]
                   [core-async-bug.macros :refer [case-let]])
  (:require [cljs.core.async :refer[ put! chan ]]))

(enable-console-print!)

; بلوك go با case دستی + lets - کار می‌کند
(let [c (chan)]
  (go
    (let [msg (      (case (first msg)
        :a (let [[x] (rest msg)] (println "First :a" x))
        :b (let [[y] (rest msg)] (println "First :b" y))))
(  

): case-let خارج از go - کار می‌کند
(case-let [:b 123]
  :a ([x] (println "Second :a" x))
  :b ([y] (println "Second :b" y)))

; case-let در داخل go - خراب است
(let [c (chan)]
  (go
    (case-let (      :a ([x] (println "Third :a" x))
      :b ([y] (println "Third :b" y))))
(  


خروجی کنسول براوزر


Second :b 123
First :b 123
Third :a 123          <-- نمی‌بایست باشند!
Third :b 123

3 پاسخ

0 رای
by
0 رای
by
_评论者:tslocke_

我发现了一个简单的解决方案。在宏展开期间,核心名称(例如 case)变得完全限定,即 cljs.core/case,这似乎导致 go 宏无法识别 case。将定义 let-case 中的 {{case}} 替换为 {{~'case}} 可以修复问题。

希望这能帮助那些了解 core.async 代码库的人轻松修复问题。

工作宏如下


(defmacro case-let [expr & cases]
  (let [msg (gensym)]
    `(let [~msg ~expr]
       (~'case (first ~msg)
        ~@(apply concat (for [[key [args & body]] (partition 2 cases)]
                    [key `(let [~args (rest ~msg)] ~@body)]))))))
0 رای
by
参考: https://clojure.atlassian.net/browse/ASYNC-79(由 alex+import 报告)
...