假设我有以下函数来从字节缓冲区获取数值:
(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/