gpt4 book ai didi

map - 为什么绑定(bind)会影响我的 map 类型?

转载 作者:行者123 更新时间:2023-12-03 14:55:41 25 4
gpt4 key购买 nike

我在 REPL 中玩耍时遇到了一些奇怪的行为:

Clojure 1.4.0
user=> (type {:a 1})
clojure.lang.PersistentArrayMap
user=> (def x {:a 1})
#'user/x
user=> (type x)
clojure.lang.PersistentHashMap

我认为所有小的文字映射都是 PersistentArrayMap 的实例,但如果它与 def 绑定(bind),显然情况并非如此。 .为什么要使用 def导致 Clojure 为我的小 map 选择不同的表示?我知道这可能只是一些奇怪的实现细节,但我很好奇。

最佳答案

这个问题让我深入研究了 Clojure 源代码。为了弄清楚这一点,我只花了几个小时将打印语句放入源代码中。

事实证明,这两个映射表达式是通过不同的代码路径评估的
(type {:a 1})导致发出并运行 Java 字节码。发出的代码使用 clojure.lang.RT.map()构造返回 的映射持久数组映射 对于小 map :

static public IPersistentMap map(Object... init){
if(init == null)
return PersistentArrayMap.EMPTY;
else if(init.length <= PersistentArrayMap.HASHTABLE_THRESHOLD)
return PersistentArrayMap.createWithCheck(init);
return PersistentHashMap.createWithCheck(init);
}

在评估 (def x {:a 1}) 时至少从 REPL 中没有发出字节码。常量映射被解析为 持久哈希映射 clojure.lang.Compiler$MapExpr.parse()它返回它在 ConstantExpr 中扭曲它:
else if(constant)
{
IPersistentMap m = PersistentHashMap.EMPTY;
for(int i=0;i<keyvals.length();i+= 2)
{
m = m.assoc(((LiteralExpr)keyvals.nth(i)).val(), ((LiteralExpr)keyvals.nth(i+1)).val());
}
//System.err.println("Constant: " + m);
return new ConstantExpr(m);
}
def求值时的表达式绑定(bind) ConstantExpr 的值如前所述,在上面创建的是 持久哈希映射 .

那么为什么要这样实现呢?

我不知道。这可能是简单的疏忽,或者 PersistentArrayMap 优化可能并不值得。

关于map - 为什么绑定(bind)会影响我的 map 类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11991694/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com