一个Clojure绑定问题

时间:2011-09-26 00:18:48

标签: clojure

只是想重新考虑一些简单的代码

我有一个功能

(defn foo
    ([x y]
        (let [line [x y]]
            (...))
    ([x y z]
        (let [plane [x y z]]
            (...))))

我知道我可以写

(let [[x y :as point] [1 0]])

我可以编写foo之类的函数进行类似的解构 实际定义中[x y :as line][x y z :as plane]? (即飞机将被分配[x y z])

2 个答案:

答案 0 :(得分:2)

您也可以在arg列表中进行解构,但是您必须使用可变参数args,这意味着您不能拥有多个签名:

(defn foo [& [x y z :as plane]]
  (...))

然后打电话给:

(foo 1 2 3)

但就像我上面所说的那样,使用这种方法,两个和三个arg形式变得模棱两可,所以你必须有单独的命名函数。

答案 1 :(得分:2)

您始终可以使用宏构建let。这将使你能够写两个类似的东西:

(def foo
  (build-foo-args [[x y] line]
     (...))
  (build-foo-args [[x y z] plane]
     (...)))

不确定这种语法糖真的会给你带来多少......首先让我们很清楚。

总的来说,我可能会建议您重新考虑您的功能签名:

  • 如果你真的需要不同的行为,那么 foo应该被分成单独的函数。

  • 如果不同的行为是相同的,那么我会使用 Dave Ray建议的可变参数,但称之为组合 争论中立的话“normal-vector”,可以指多个 维度。您可能会发现实际上并不需要x,y,z来命名....