Списки против кортежей - что использовать и когда?
Я пытаюсь понять разницу между списками и Tuples в Elixir
. Из раздела Основные типы в Elixir Guides я понимаю, что:
- Списки хранятся в виде связанных элементов.
- Обновление списка выполняется быстро (только при добавлении)
- Элементы списка Fetching медленны
- Информация о наборе списка (размер/длина) медленная
- Элементы Tuple хранятся вместе
- Получение информации о Tuple быстро
- Элементы Fetching Tuple быстро
- Изменение кортежей дорого.
Хорошо, что все отлично, но я все еще не уверен, что использовать, когда. Я вижу, что большинство методов возвращают кортеж, но везде используются списки, и многие методы принимают списки как входные, а не кортежи. В соответствии с указанными выше пунктами не следует использовать Tuples для передачи данных вокруг, так как чтение из кортежа заданных пользователем значений будет быстрым?
Я также заметил, что Tuples не перечислимы, что с этим? Не использовал бы Enum
над ними быстрее, чем использовать его в списках?
Если кто-то может помочь мне понять их лучше, возможно, представив несколько примеров того, что использовать, когда это будет потрясающе.
Ответы
Ответ 1
Вы уже дали довольно хорошее резюме различий, поэтому в любых условиях, где важна одна из этих вещей, она должна помочь вам принять решение о том, что использовать.
Способ думать об этом состоит в том, что списки представляют собой структуры с открытым контентом, и их размер может варьироваться во время выполнения, в то время как Tuples имеют постоянный размер, установленный во время компиляции.
Например, если вы хотите сохранить все команды, предоставленные пользователем во время сеанса iex
, вам нужен список - длина этого списка будет зависеть от количества команд, заданных в этом сеансе. Сравните это с типичным прецедентом для кортежей - возвращая {:ok, result}
или {:error, reason}
из метода - здесь количество элементов известно заранее, и поэтому вы не платите недопустимую цену за улучшение производительности Tuples.
Что касается перечисления - кортежи концептуально не являются коллекциями, и каждая позиция элемента должна также обозначать ее роль. Рассмотрим {:ok, #PID<0.336.0>}
Tuple - итерацию по нему сначала даст вам :ok
, а затем a #PID<0.336.0>
, было бы очень странно писать функцию, действующую равномерно на эти вещи.
Ответ 2
Я не эксперт, но это мое понимание:
Под капотом список - это связанный список. Следовательно, он получил характеристики производительности связанного списка. То есть, длина равна O (n), потому что мне нужно пройти весь список. Аналогично, список имеет преимущества связанного списка; то есть легко вырастить его, добавив к фронту.
Я не уверен, что кортеж находится под капотом, но я знаю, что это не связанный список. Кто-то попросил перечислить кортежи в списке рассылки Elixir еще в 2013 году, и это часть ответа:
"Кортежи также не должны повторяться, не путайте тот факт, что вы могли использовать elem/2 и size/1. Кортежи предназначены для хранение нескольких фрагментов информации вместе, что не означает что они предназначены для хранения коллекции".
- Питер Минтен
"Еще одно объяснение заключается в том, что кортежи - это плохие записи человека. другими словами, кортеж представляет собой единый фрагмент данных, один ценность, хотя и совокупность. Вы не можете отнять элемент из кортежа без изменения семантического значения этого конкретного значения кортежа.
" Это противоречит спискам и другим коллекциям, в которых хранятся многие значения независимых значений. Извлечение ценности из списка просто уменьшает длину списка. Это не влияет на семантический смысл что-нибудь ".
- Алексей Шолик
Другими словами, только потому, что существует поверхностное сходство между кортежами и списками, нельзя предполагать, что поведение одинаковое.
Ответ 3
В дополнение к тому, что уже было сказано, то, что помогло мне дифференцировать кортеж из списка, аналогично строке в базе данных. Если вы думаете о кортеже, таким образом, легко увидеть, как информация в кортеже связана друг с другом, и становится очевидным, почему вы не будете использовать его как Enumerable.
Ответ 4
Так как кто-то упомянул, что они не уверены, что кортеж напоминает под капотом, кортеж будет похож на массив, так как массивы и кортежи хранят элементы в смежной памяти. Таким образом, те же правила будут следовать, когда вы будете использовать массив над связанным списком, как это было бы с кортежем над списком в Elixir.
Ответ 5
Если вы знакомы с Java:
- Список похож на
LinkedList
.
- Кортеж похож на
ArrayList
.