freeCodeCamp/guide/chinese/clojure/lists-are-everything/index.md

107 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

---
title: Clojure Lists They Are Everything
localeTitle: Clojure列出他们就是一切
---
列表是Clojure的基础。 Clojure是一个Lisp而Lisps最初用于列表处理。 Lisp中的所有内容都是一个列表
```
(def foo "bar")
```
那段代码实际上是一个列表! Clojure中的两个圆括号之间也是如此。有意思不是吗这就是使Lisps如此有趣的原因 - 您可以轻松编写生成新代码的代码,因为生成代码就像创建列表一样简单。
## 制作一个实际的清单
问题是因为一切都是Clojure中的列表这样的东西会返回一个错误
```
(1 2 3 4 5)
; => ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn
```
多么可怕的错误信息。 REPL试图告诉我们的是“1不是一个功能它不能合而为一。”因为Lisp中的所有内容都是一个列表所以任何列表中的第一项都被视为函数如`def` `+`或`str` ,所以如果我们写`(1 2 3 4 5)` ,它会将第一个元素( `1` )视为一个功能,它显然不是。
我们可以用两种方式解决这个问题。一种是使用`list`函数构造一个列表,比如使用`str`将字符串连接在一起。
```
(list 1 2 3 4 5)
; => (1 2 3 4 5)
```
您也可以使用报价。引用一个列表实际上是告诉编译器该列表_不是_函数调用它不应该评估其中的任何代码。
```
'(1 2 3 4 5)
; => (1 2 3 4 5)
```
有趣的是,您也可以引用函数调用。这就是宏的工作原理。它们非常复杂,值得拥有自己的文章,所以我们在此不再赘述。
```
;; Without a ' to quote it, this would return "foobarbaz".
'(str "foo" "bar" "baz")
; => (str "foo" "bar" "baz")
```
![:rocket:](//forum.freecodecamp.com/images/emoji/emoji_one/rocket.png?v=2 ":火箭:") [IDEOne吧](https://ideone.com/6c7UxY)
## 添加到列表
列表是为前置而非附加而设计的。没有真正的方法可以附加到列表中。您可以使用`cons`前置到列表中。 `conj`也可以工作,但是这对于向量来说是有意义的,对于列表而言, `cons`更快。
```
(cons 1 '(2 3 4))
; => (1 2 3 4)
```
## 从列表中检索
您可以使用`nth`从列表中检索项目。 `get`不适用于列表,因为列表是为顺序访问而设计的,而不是随机访问。请注意, `nth`适用于矢量,但由于这个原因比`get`慢。
```
(nth '(1 2 3 4) 0)
; => 1
```
## 将其他集合转换为列表
`list`函数无法将其他集合转换为列表,因为它尝试使用给定的参数构造列表。传递`list`集合将返回包含该集合的列表。
```
(list [1 2 3 4 5])
; => ([1 2 3 4 5])
```
要转换为列表,请改用`seq`函数。
```
(seq [1 2 3 4 5])
; => (1 2 3 4 5)
```
## 懒惰的序列
Clojure有一个很棒的功能叫做“懒惰序列”。延迟序列是一个列表其元素在您稍后引用序列的元素之前不会生成此时它会评估序列的所有元素直到您想要的元素。这允许您构建“无限”序列
`range`可能是最简单的懒惰序列。它包含所有数字。
```
(range 10)
; => (0 1 2 3 4 5 6 7 8 9)
(range -5 5)
; => (-5 -4 -3 -2 -1 0 1 2 3 4)
```
你可以使用懒惰的序列来做很酷的事情,比如生成所有斐波纳契数的懒惰序列。
```
(def fibs
(lazy-cat [0 1] (map + (rest fibs) fibs)))
(take 10 fibs) ;; this means, "evaluate the first 10 fibonacci numbers."
; => (0 1 1 2 3 5 8 13 21 34)
```
这个例子有点高级,如果你是初学者,你不应该理解它。这只是一个你可以用懒惰序列做的很酷的例子。也许你无论如何都可以搞清楚!
![:rocket:](//forum.freecodecamp.com/images/emoji/emoji_one/rocket.png?v=2 ":火箭:") [IDEOne吧](https://ideone.com/jwpvt8)
## 什么时候使用清单?
使用向量通常比使用列表更可取因为编译器不会意外地将向量作为函数进行评估并且访问向量的任意元素的速度更快。列表在3种情况下最有用
* 使用宏生成代码。
* 生成“无限”的懒惰序列。
* 将元素添加到集合中。
| [![:point_left:](//forum.freecodecamp.com/images/emoji/emoji_one/point_left.png?v=2 "point_left")上一页](//forum.freecodecamp.com/t/clojure-collections/18411) | [![:book:](//forum.freecodecamp.com/images/emoji/emoji_one/book.png?v=2 ":书:")家![:book:](//forum.freecodecamp.com/images/emoji/emoji_one/book.png?v=2 ":书:")](//forum.freecodecamp.com/t/clojure-resources/18422) | [下一个![:point_right:](//forum.freecodecamp.com/images/emoji/emoji_one/point_right.png?v=2 "point_right")](//forum.freecodecamp.com/t/clojure-vectors/18421) |
| [收藏](//forum.freecodecamp.com/t/clojure-collections/18411) | [目录](//forum.freecodecamp.com/t/clojure-resources/18422) | [矢量](//forum.freecodecamp.com/t/clojure-vectors/18421) |