clojure - 在 Clojure 中返回表达式序列中非最后一个表达式的值的惯用方法

标签 clojure let

假设我有以下函数来从字节缓冲区获取数值:

(defn get-from-bytebuffer
  ([^ByteBuffer buffer width endianness]
    (let [buffer-endianness (.order buffer)]
      (.order buffer endianness)
      (cond
        (= width 1) (.get buffer)
        (= width 2) (.getShort buffer)
        (= width 4) (.getInt buffer)
        (= width 8) (.getLong buffer))
      (.order buffer buffer-endianness))))

用户可以指定正在读取的数字的字节顺序。为了将副作用降至最低,该函数首先获取缓冲区的当前字节顺序,将其设置为用户指示的字节顺序,然后恢复旧的字节顺序。这样做的问题是 let 正文中最后一个表达式的值是 let 表达式的值,但我需要 的值条件。更一般地说,我在表达式周围有一些序言/结尾代码,但我希望返回表达式的结果(作为封闭表达式的值。)

我想出的简单解决方法只是将 cond 的值绑定(bind)到另一个 let 表达式中,然后将其作为最后一个表达式,如下所示:

(defn get-from-bytebuffer-fix
  ([^ByteBuffer buffer width endianness]
    (let [buffer-endianness (.order buffer)]
      (.order buffer endianness)
      (let [result (cond
                     (= width 1) (.get buffer)
                     (= width 2) (.getShort buffer)
                     (= width 4) (.getInt buffer)
                     (= width 8) (.getLong buffer))]
      (.order buffer buffer-endianness)
      result))))

但这感觉很笨拙。 Clojure 是否有一种惯用/“正确”的方式用一些序言/尾声代码包围表达式,然后返回该表达式的值?

最佳答案

也许下面的替代方案之一是可以接受的。

(let [buffer-endianness (.order buffer)
      _ (.order buffer endianness)
      result (cond
               (= width 1) (.get buffer)
               (= width 2) (.getShort buffer)
               (= width 4) (.getInt buffer)
               (= width 8) (.getLong buffer))
      _ (.order buffer buffer-endianness)]
  result)

(let [buffer-endianness (.order buffer)]
  (try 
    (.order buffer endianness)
    (cond
      (= width 1) (.get buffer)
      (= width 2) (.getShort buffer)
      (= width 4) (.getInt buffer)
      (= width 8) (.getLong buffer))
    (finally (.order buffer buffer-endianness))))

(defn return-nth [n & exprs]
  (nth exprs n))

(return-nth 1
  'exp-0
  'exp-1
  'exp-2)

(nth ['exp-0 'exp-1 'exp-2] 1)

另请注意

(cond
  (= width 1) (.get buffer)
  (= width 2) (.getShort buffer)
  (= width 4) (.getInt buffer)
  (= width 8) (.getLong buffer))

可以写

(case width
  1 (.get buffer)
  2 (.getShort buffer)
  4 (.getInt buffer)
  8 (.getLong buffer))

关于clojure - 在 Clojure 中返回表达式序列中非最后一个表达式的值的惯用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20451676/

相关文章:

rest - 在 clojure 中,如何将列表传递给参数化函数(以及更多)

logging - 如何决定哪些附加程序对 `clojure.tools.logging` 的日志进行操作?

f# - F# 函数签名的字符串表示形式

javascript - 循环中的 let 语句在 IE 中无法正常工作

haskell - 不使用 in 时 let 的范围是什么?

html - 我在哪里可以找到 compojure.html?

data-structures - Clojure 中 2D 游戏板的适当表示

haskell - 为什么在 do block 中需要 let 关键字?

javascript - 让 vs var 在 javascript 中

clojure - 在嵌套映射中查找特定键的值