Clojure - 解构



解构是 Clojure 中的一项功能,它允许您从数据结构(如向量)中提取值,并将它们绑定到符号,而无需显式遍历数据结构。

让我们来看一个关于解构的具体含义及其工作方式的例子。

示例

(ns clojure.examples.example
   (:gen-class))
(defn Example []
   (def my-vector [1 2 3 4])
   (let [[a b c d] my-vector]
   (println a b c d)))
(Example)

以上程序产生以下输出。

输出

1 2 3 4

在以上示例中,需要注意以下几点:

  • 我们定义了一个包含整数 1、2、3 和 4 的向量。

  • 然后,我们使用‘let’语句将 4 个变量(a、b、c 和 d)直接分配给 my-vector 变量。

  • 如果我们对这四个变量运行‘println’语句,我们可以看到它们已经被分别分配给了向量中的值。

因此,Clojure 在使用 'let' 语句赋值时,对包含四个值的 my-vector 变量进行了解构。解构后的四个值随后被相应地分配给了四个参数。

如果存在没有对应值的额外变量,则它们将被分配为 nil 值。以下示例说明了这一点。

示例

(ns clojure.examples.hello
   (:gen-class))
(defn Example []
   (def my-vector [1 2 3 4])
   (let [[a b c d e] my-vector]
   (println a b c d e)))
(Example)

以上程序产生以下输出。您可以从输出中看到,由于最后一个变量 'e' 在向量中没有对应值,因此它等于 nil。

输出

1 2 3 4 nil

the-rest

‘the-rest’ 变量用于存储无法分配给任何变量的剩余值。

以下程序显示了如何使用它。

示例

(ns clojure.examples.example
   (:gen-class))
(defn Example []
   (def my-vector [1 2 3 4])
   (let [[a b & the-rest] my-vector]
   (println a b the-rest)))
(Example)

以上程序产生以下输出。从输出中,您可以清楚地看到,3 和 4 的值无法分配给任何变量,因此它们被分配给了 ‘the-rest’ 变量。

输出

1 2 (3 4)

解构映射

就像向量一样,映射也可以被解构。以下是如何实现此操作的示例。

示例

(ns clojure.examples.example
   (:gen-class))
(defn Example []
   (def my-map {"a" 1 "b" 2})
   (let [{a "a" b "b"} my-map]
   (println a b)))
(Example)

以上程序产生以下输出。从程序中您可以清楚地看到,映射中 “a” 和 “b” 的值被分配给了变量 a 和 b。

输出

1 2

类似于向量的情况,如果在解构发生时映射中没有对应值,则变量将被分配 nil 值。

以下是一个示例。

示例

(ns clojure.examples.example
   (:gen-class))
(defn Example []
   (def my-map {"a" 1 "b" 2})
   (let [{a "a" b "b" c "c"} my-map]
   (println a b c)))
(Example)

以上程序产生以下输出。

输出

1 2 nil
广告