在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-b
和a_b
符号最终变成了var a_b_531
和var 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
有问题的情况