---
title: Clojure Lists They Are Everything
localeTitle: Clojure Списки Они все
---
Списки являются фундаментальными для Clojure. Clojure - это Lisp, а Lisps были первоначально использованы для обработки списка. Все в Лиспе - это список!
```
(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)

## Когда использовать список?

Использование вектора обычно предпочтительнее использования списка, так как нет никакого риска, что компилятор случайно оценивает вектор как функцию, и быстрее получить доступ к произвольным элементам вектора. Списки наиболее полезны в трех случаях:

*   Создание кода с использованием макроса.
*   Создание «бесконечных» ленивых последовательностей.
*   Предоставление элементов коллекции.

| [![: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) |