2024 Clojure状态调查!分享您的看法。

欢迎!请查看关于页面了解有关此功能的一些更多信息。

+2
ClojureScript
编辑

在clojurescript repl中的这个表达式

(let [{:keys [a-b a_b]} {:a-b 0 :a_b 1}] [a-b a_b])

会出人意料地返回

[1 1]

我在创建一个类似Clojurescript官方指南的清洁项目中进行了进一步调查

(ns helloworld.core)

;; two identical code blocks

;; first one is at top level
(let [{:keys [a-b a_b]} {:a-b 0 :a_b 1}] [a-b a_b])
;; second one nested inside a function call
(println (let [{:keys [a-b a_b]} {:a-b 0 :a_b 1}] [a-b a_b]))

并使用以下编译

clj -M --main cljs.main --compile helloworld.core

这是js文件

// Compiled by ClojureScript 1.10.866 {:optimizations :none}
goog.provide('helloworld.core');
goog.require('cljs.core');
var map__528_529 = new cljs.core.PersistentArrayMap(null, 2, [new cljs.core.Keyword(null,"a-b","a-b",-1660985764),(0),new cljs.core.Keyword(null,"a_b","a_b",-1795286609),(1)], null);
var map__528_530__$1 = cljs.core.__destructure_map.call(null,map__528_529);
var a_b_531 = cljs.core.get.call(null,map__528_530__$1,new cljs.core.Keyword(null,"a-b","a-b",-1660985764));
var a_b_532 = cljs.core.get.call(null,map__528_530__$1,new cljs.core.Keyword(null,"a_b","a_b",-1795286609));
new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [a_b_531,a_b_532], null);
cljs.core.println.call(null,(function (){var map__533 = new cljs.core.PersistentArrayMap(null, 2, [new cljs.core.Keyword(null,"a-b","a-b",-1660985764),(0),new cljs.core.Keyword(null,"a_b","a_b",-1795286609),(1)], null);
var map__533__$1 = cljs.core.__destructure_map.call(null,map__533);
var a_b = cljs.core.get.call(null,map__533__$1,new cljs.core.Keyword(null,"a-b","a-b",-1660985764));
var a_b = cljs.core.get.call(null,map__533__$1,new cljs.core.Keyword(null,"a_b","a_b",-1795286609));
return new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [a_b,a_b], null);
})());

//# sourceMappingURL=core.js.map

如您所见

  • 第一块中的a-ba_b符号最终变成了var a_b_531var a_b_532
  • 在第二块中,两者最终都变成了var a_b,因此它们的值发生了冲突。

我也用使用cljs.core/let*宏展开后的版本得到了相同的结果

(let* [m {:a-b 0, :a_b 1}
       a-b
       (cljs.core/get m :a-b)
       a_b
       (cljs.core/get m :a_b)]
  [a-b a_b])

(println 
 (let* [m {:a-b 0, :a_b 1}
        a-b
        (cljs.core/get m :a-b)
        a_b
        (cljs.core/get m :a_b)]
   [a-b a_b]))

因此我们可以排除宏展开的cljs.core/let有问题的情况

登录注册以回答此问题。

...