12

在 Python 中,您可以将列表或元组传递给函数并让函数解包参数。我怎样才能在 Clojure 中做到这一点?这是一些示例 Python 代码:

def f (a, b, c, *d):
    print "a: ", a
    print "b: ", b
    print "c: ", c
    print "d: ", d

f (1, 2, 3, 4, 5, 6)

print
v = (4, 5, 6)
f(1, 2, 3, *v)

结果:

a:  1
b:  2
c:  3
d:  (4, 5, 6)

a:  1
b:  2
c:  3
d:  (4, 5, 6)

在我的clojure代码中:

(defn f [a b c & d]
  (println "a: " a)
  (println "b: " b)
  (println "c: " c)
  (println "d: " d))

(f 1 2 3 4 5 6)

(println)
(def v [4 5 6])
(f 1 2 3 v)

结果:

a:  1
b:  2
c:  3
d:  (4 5 6)

a:  1
b:  2
c:  3
d:  ([4 5 6])

d 只有一个元素,我怎样才能让结果作为 python 代码?

4

3 回答 3

13

Clojure 不会像 Python 那样从具有语言特性的向量中解压缩参数。

最接近解包的是函数apply

在这种特殊情况下:

(def v [4 5 6])
(apply f (concat [1 2 3] v))

印刷:

a:  1
b:  2
c:  3
d:  (4 5 6)
于 2012-05-29T15:43:07.323 回答
5

只是为了完整性。

假设您有一个将向量[d1 d2 d3]作为参数的函数

(defn f
  [a b c [d1 d2 d3]]
  (println "a: " a)
  (println "b: " b)
  (println "c: " c)
  (println "d1: " d1)
  (println "d2: " d2)
  (println "d3: " d3))

这样,我们可以从传递给函数的向量中获取前 3 项f作为d1 d2 d3. 调用上述函数会产生以下输出:

=> (f 1 2 3 [6 7 8 9])
a:  1
b:  2
c:  3
d1:  6
d2:  7
d3:  8

请注意,即使向量包含 4 个项目,我们也只取前 3 个。

于 2012-11-20T22:18:18.023 回答
0

对于 Clojure 中的任何参数,您可以通过使用顺序来确定参数是标量值还是序列?在下面的伪代码中,

(if (sequential? v)
   (do-something-because-it's-a-sequence v)
   (do-something-different-because-it's-not-a-sequence v))

因此,在 Clojure 中,您可以通过确定是否有序列来完成与 Python 示例中相同的任务。

于 2012-05-29T22:43:46.820 回答