Из двух включенных здесь функций, что является более идиоматическим из двух?Не представляют ли что-то, что можно считать хорошим Clojure?Есть ли более элегантный способ сделать это?Ищите конструктивную критику в отношении стиля / направления.
(на 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: loop / recur
На каждом уровне рекурсии рассматриваемый байт смещается влево на число, соответствующее количеству байтов на данном данном уровнерекурсия, затем добавляется к текущей сумме и либо возвращается, либо переходит на другой уровень.
(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: при уменьшении
v2 сокращает вектор байтов с помощью аккумулятора [sumposition] где:
- 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)))