为什么绑定会影响我的地图类型? [英] Why does binding affect the type of my map?

查看:167
本文介绍了为什么绑定会影响我的地图类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆