字段方法不允许使用多个子块

时间:2014-09-19 14:28:15

标签: java clojure

我从网上获得了这段java代码

import java.util.zip.CRC32;

public static short getCRC(String s, int i, byte bytes[])
{
      CRC32 crc32 = new CRC32();
      if (s != null)
      {
          for (int j = 0; j < s.length(); j++)
          {
              char c = s.charAt(j);
              crc32.update(c);
          }
      }
      crc32.update(i);
      crc32.update(i >> 8);
      crc32.update(i >> 16);
      crc32.update(i >> 24);
      for (int k = 0; k < bytes.length; k++)
      {
          byte byte0 = bytes[k];
          crc32.update(byte0);
      }
      return (short) (int) crc32.getValue();
}

我尝试将其翻译为Clojure:

(defn getCRC [s i bytes]
    (let [crc32 (CRC32.)]
        (if (not= s nil)
            (for [c s] (.update crc32 (int c)))
        )
        (map #(.update crc32 (int (bit-shift-right i %))) [0 8 16 24])
        (for [c bytes]
            (.update crc32 (int c))
        )
        (.getValue crc32)
    )
)

但似乎.update不起作用,函数返回0 我评估了let身体中的每个块,它运行正常 我还在.update之前添加了另一个.getValue数字,它工作正常,函数的返回值成为它的CRC32;
但当我将它们捆绑在一起时,返回值再次变为0。

非常感谢任何帮助或想法!

1 个答案:

答案 0 :(得分:2)

问题在于formap都会产生惰性序列。

由于您不会在代码中的任何位置强制执行结果,因此无法实现序列,并且永远不会调用.update

尝试将两者同时用于doseq - 一种专门处理副作用的迭代形式(其他事情并非懒惰),并查看它如何改变结果:

(defn getCRC [s i bytes]
    (let [crc32 (CRC32.)]
        (if (not= s nil)
            (doseq [c s] (.update crc32 (int c)))
        )
        (doseq [x [0 8 16 24]] (.update crc32 (int (bit-shift-right i x))))
        (doseq [c bytes]
            (.update crc32 (int c))
        )
        (.getValue crc32)
    )
)