这两个函数中,哪一个更符合惯用的方式?它们都不能代表一种可以被认为是良好的Clojure吗?有没有更优雅的方法来完成这个任务?寻求对样式/方向的建设性批评。
(在github上:https://github.com/jtrim/clojure-sandbox/blob/master/bit-sandbox/src/bit_sandbox/core.clj#L25)
这两个函数的版本都接受一个表示字节的数字向量,并将字节转换为数字。例如:
(在github上:https://github.com/jtrim/clojure-sandbox/blob/master/bit-sandbox/src/bit_sandbox/core.clj#L25)
这两个函数的版本都接受一个表示字节的数字向量,并将字节转换为数字。例如:
(bytes-to-num [0 0 0 0]) ;=> number `0`
(bytes-to-num [0 0 0 255]) ;=> number `255`
(bytes-to-num [0 0 1 0]) ;=> number `256`
; etc...
v1: 循环/递归
在每个递归层级中,所涉及的字节会左移一个与该递归层级的字节数相对应的数字,然后加到运行总和中,最后返回或传递到另一个层级。
(defn bytes-to-num-v1 [vec-bytes]
(loop [sum 0, the-bytes vec-bytes]
(if (empty? the-bytes)
sum
(recur
(+ sum (shifted-byte (first the-bytes) (count (rest the-bytes))))
(rest the-bytes)))))
v2: reduce
v2使用一个累加器[sum position]来减少字节向量,其中:
- sum:移位字节的运行总和
- position:向量中当前字节的从右到左的零基索引(注意:不是从左到右)。用于确定要将问题字节左移多少位。
:
(defn bytes-to-num-v2 [vec-bytes]
(first (reduce
(fn [acc, the-byte]
[(+ (first acc) (shifted-byte the-byte (last acc))) (dec (last acc))])
[0 (dec (count vec-bytes))]
vec-bytes)))
以下是 shifted-byte
函数的源代码,供完整性参考:
(defn shifted-byte [num-byte-value, shift-by]
(bit-shift-left
(bit-and num-byte-value 0xFF)
(* shift-by 8)))
to-signed-byte
也可以使用Byte/valueOf
。(defn t-s-b [x] (Byte/valueOf (byte x)))
。它为您执行转换。 - kotarak