Dav*_*ood 4 clojure destructuring
直到现在,我一直假设你可以在let绑定中做的任何事情,你都可以在defn表单的参数向量中做。
但是,我刚刚注意到这一点——如果我用let绑定来做到这一点,它会起作用:
(let [[x & more :as full-list] (range 10)]
(println "x:" x)
(println "more:" more)
(println "full list:" full-list))
; x: 0
; more: (1 2 3 4 5 6 7 8 9)
; full list: (0 1 2 3 4 5 6 7 8 9)
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试将其提取到函数中,则会出现异常:
(defn foo [x & more :as full-list]
(println "x:" x)
(println "more:" more)
(println "full list:" full-list))
; CompilerException java.lang.RuntimeException: Unexpected parameter, compiling:(/tmp/form-init615613631940782255.clj:1:1)
Run Code Online (Sandbox Code Playgroud)
值得注意的是,这有效:
(defn foo [[x & more :as full-list]]
(println "x:" x)
(println "more:" more)
(println "full list:" full-list))
Run Code Online (Sandbox Code Playgroud)
但是然后我必须将参数作为集合传递,即(foo [1 2 3]).
是否可以定义一个接受可变数量参数的函数,并将整组参数绑定到一个局部变量,而无需let在内部专门使用绑定?这让我觉得很奇怪,你不能只是这样做(defn foo [x & more :as full-list] ...是否有特殊的原因为什么这不起作用(或不应该)?
如果您想要可变数量的 args,则缺少 &:
(defn foo [& [x & more :as full-list]]
(println "x:" x)
(println "more:" more)
(println "full list:" full-list))
Run Code Online (Sandbox Code Playgroud)
Clojure 参数定义只有一种特殊情况,即&表示可变参数数量的字符。其余的是简单的命名参数。
现在每个简单的参数都可以使用 map 或 list 语法进行解构。例如:
(defn foo [ x y ] ...)
Run Code Online (Sandbox Code Playgroud)
可以像这样解构:
(defn foo [[x1 x2 & x-more :as x] {:keys [y1 y2 y3]}] ...)
Run Code Online (Sandbox Code Playgroud)
所以我们说我们希望第一个参数是一个至少包含 2 个元素的列表,第二个参数是一个带有一些键的映射。请注意,这仍然是一个包含两个参数的 fn,并且 Clojure 不会强制 x 实际上至少有两个元素。如果 x 是空列表,则 x1 和 x2 将为 nil。
回到你的问题,如果你看我的回答,你会发现我的 fn 有 0 个强制参数,参数数量可变,而你的 fn 有 1 个强制参数,参数数量可变。我正在做的只是解构 var arg。
| 归档时间: |
|
| 查看次数: |
474 次 |
| 最近记录: |