【问题标题】:Is it possible to override .toString for a typed Java-Array in Clojure?是否可以在 Clojure 中为类型化的 Java-Array 覆盖 .toString?
【发布时间】:2013-12-17 10:24:46
【问题描述】:

我有一个像这样的字节数组:

(def byte-arr (byte-array (map byte "This is a test"))) ; => #<byte[] [B@63465272>

当调用.toString 时,我得到[B@1b96107b。在这种情况下,是否可以覆盖 clojure 类型 [B.toString-Method 以获取 This is a test

【问题讨论】:

    标签: clojure overriding clojure-java-interop


    【解决方案1】:

    全局假设所有字节数组都是可打印的字符串是一个坏主意,因此仅使用 String 构造函数的建议是正确的。也就是说,您可以按类型全局添加新的打印。

    打印功能最终会转为调用print-methodprint-dup 多方法,具体取决于*print-dup* 是否为真。您可以使用core_print.clj 中的print-sequential 辅助函数向print-method 添加新方法,如下所示:

    (in-ns 'clojure.core)
    
    (def ^:private ByteArray (type (byte-array 0)))
    
    (defmethod print-method ByteArray [ba ^Writer w]
      (print-sequential "[" pr-on " " "]" ba w))
    

    注意这只是打印一个字节数组,就好像它是一个字节向量:

    clojure.core=> (in-ns 'user)
    #<Namespace user>
    user=> (byte-array (map byte "This is a test"))
    [84 104 105 115 32 105 115 32 97 32 116 101 115 116]
    

    【讨论】:

      【解决方案2】:

      我不建议覆盖 toString。这是太多的全局变化,你可能会破坏一些依赖默认行为的东西。

      为什么不为您的特定需求创建一个函数?

      【讨论】:

      • 我从未尝试过 reify(我也不能说我完全理解它是如何工作的,或者我会在哪里使用它)。但是是否可以将 reify 用于该用例?
      • reify 适用于您想要某个接口、协议和/或对象的一次性实例的情况。如果可以将 proxy 与 Java 的原始数组一起使用,那么它会更合适,但根据我的经验和我尝试过的事情,它似乎不是。 @AlexTaggart 解决方案对我来说似乎是最好的。
      • 感谢您的澄清!
      【解决方案3】:

      只需 construct a String 带有该字节数组的对象:

      (println (String. byte-arr))
      

      【讨论】:

        猜你喜欢
        • 2012-05-04
        • 1970-01-01
        • 2015-05-08
        • 1970-01-01
        • 2012-07-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-11
        相关资源
        最近更新 更多