如何将可变参数函数的其余参数传递给另一个函数?
How to pass the rest args of a variadic function to another function?
我想编写一个函数,它只用新值更新映射中的向量,但可以接受任意数量的参数,但至少有一个。
示例如下:
(defn my-update [what item & items]
(update what :desired-key conj item items))
不幸的是,这不起作用。尽管 update
确实有一个包含多个值的签名(如 [m k f x y]
),但 my-update
的所有剩余参数将被连接成一个序列,该序列将传递给 conj
作为一个参数。
相反,在匿名函数中用 apply
包装 conj
确实有效,但看起来不太优雅:
(defn my-update [what item & items]
(update what :desired-key #(apply conj % item items))
像my-update
这样的函数的惯用写法是什么?
您现有的解决方案还不错。一个小的改进是使用 into
函数,它在内部使用 conj
将两个序列连接在一起:
(defn my-update [what & items]
(update what :a into items))
结果
(my-update {:a [1]} 2 3 4) => {:a [1 2 3 4]}
另一种方法是将匿名函数提取到命名函数中:
(defn append-to-seq
[seq item items]
(-> (vec seq) ; ensure it is a vector so conj adds to the end, not beginning
(conj item)
(into items)))
(defn my-update [what item & items]
(update what :a append-to-seq item items))
您可以在 update
之前简单地插入 apply。这将使用后面的参数调用函数 update
,除了最后一个参数应该是一个序列,其元素成为调用中的其余参数:
(defn my-update [what item & items]
(apply update what :desired-key conj item items))
(my-update {:desired-key [0]} 1 2 3 4)
;; => {:desired-key [0 1 2 3 4]}
(my-update {:desired-key [0]})
;; Exception: Wrong number of args (1) passed to: my-update
这样,您可以保留函数参数列表 [what item & items]
,清楚地表明至少需要提供一项。
一般来说,调用 (apply f a b c ... [x y z ...])
的计算结果与 (f a b c ... x y z ...)
相同。
我想编写一个函数,它只用新值更新映射中的向量,但可以接受任意数量的参数,但至少有一个。
示例如下:
(defn my-update [what item & items]
(update what :desired-key conj item items))
不幸的是,这不起作用。尽管 update
确实有一个包含多个值的签名(如 [m k f x y]
),但 my-update
的所有剩余参数将被连接成一个序列,该序列将传递给 conj
作为一个参数。
相反,在匿名函数中用 apply
包装 conj
确实有效,但看起来不太优雅:
(defn my-update [what item & items]
(update what :desired-key #(apply conj % item items))
像my-update
这样的函数的惯用写法是什么?
您现有的解决方案还不错。一个小的改进是使用 into
函数,它在内部使用 conj
将两个序列连接在一起:
(defn my-update [what & items]
(update what :a into items))
结果
(my-update {:a [1]} 2 3 4) => {:a [1 2 3 4]}
另一种方法是将匿名函数提取到命名函数中:
(defn append-to-seq
[seq item items]
(-> (vec seq) ; ensure it is a vector so conj adds to the end, not beginning
(conj item)
(into items)))
(defn my-update [what item & items]
(update what :a append-to-seq item items))
您可以在 update
之前简单地插入 apply。这将使用后面的参数调用函数 update
,除了最后一个参数应该是一个序列,其元素成为调用中的其余参数:
(defn my-update [what item & items]
(apply update what :desired-key conj item items))
(my-update {:desired-key [0]} 1 2 3 4)
;; => {:desired-key [0 1 2 3 4]}
(my-update {:desired-key [0]})
;; Exception: Wrong number of args (1) passed to: my-update
这样,您可以保留函数参数列表 [what item & items]
,清楚地表明至少需要提供一项。
一般来说,调用 (apply f a b c ... [x y z ...])
的计算结果与 (f a b c ... x y z ...)
相同。