【问题标题】:How to destructure a vector for use as a function argument如何解构向量以用作函数参数
【发布时间】:2012-06-03 19:55:02
【问题描述】:

在 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 代码?

【问题讨论】:

    标签: clojure


    【解决方案1】:

    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)
    

    【讨论】:

    • (apply f (concat [1 2 3] v)) 很好,我可以连接其他人:(apply f (concat [1 2 3] v [7 8 9]))
    【解决方案2】:

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

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

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

    【讨论】:

    • 确定d元素,使用顺序?更好, (seq? [1 2 3]) => false
    【解决方案3】:

    只是为了完整性。

    假设您有一个将向量 [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))
    

    这样我们可以从传递给函数f的向量中取出前3项作为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 个。

    【讨论】:

      猜你喜欢
      • 2022-07-14
      • 2022-01-22
      • 2013-02-22
      • 2018-03-09
      • 2020-07-22
      • 1970-01-01
      • 2012-02-14
      • 2022-01-06
      • 2014-09-03
      相关资源
      最近更新 更多