为什么绑定会影响我的地图类型? [英] Why does binding affect the type of my map?
问题描述
我在REPL中玩,我有一些奇怪的行为:
I was playing around in the REPL and I got some weird behavior:
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
绑定。为什么使用 def
导致Clojure为我的光地图选择不同的表示形式?我知道这可能只是一些奇怪的实现细节,但我很好奇。
I thought that all small literal maps were instances of PersistentArrayMap
, but apparently that's not the case if it's been bound with def
. Why would using def
cause Clojure to choose a different representation for my litte map? I know it's probably just some strange implementation detail, but I'm curious.
推荐答案
这个问题让我挖掘Clojure源码。
This question made me dig into the Clojure source code. I just spent a few hours putting print statements in the source in order to figure this out.
(类型{:a 1})
导致Java字节码被发出并运行。发出的代码使用 clojure.lang.RT.map()
构造为小地图返回 PersistentArrayMap 的地图:
(type {:a 1})
causes Java byte-code to be emitted and ran. The emitted code use clojure.lang.RT.map()
to construct the map which returns a PersistentArrayMap for small maps:
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()
中作为 PersistentHashMap 解析,它返回它在 ConstantExpr
:
When evaluating (def x {:a 1})
at least from the REPL there's no byte-code emitted. The constant map is parsed as a PersistentHashMap in clojure.lang.Compiler$MapExpr.parse()
which returns it warpped it in a 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
当评估绑定上面创建的 ConstantExpr
的值,如所述的 PersistentHashMap 。
The def
expression when evaluated binds the value of the ConstantExpr
created above which as as said is a PersistentHashMap.
我不知道。这可能是简单的监督,或者PersistentArrayMap优化可能不值得。
I don't know. It could be simple oversight or the PersistentArrayMap optimization may not really be worth it.
这篇关于为什么绑定会影响我的地图类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!