Как называется функция [foo, bar] = ["foo", "bar"]?
Мне нужно знать правильное имя для этой классной функции, которую предоставляют некоторые языки.
К вашему сведению: в некоторых языках можно выполнить несколько назначений, назначив структуру значений структуре "переменных". В примере в заголовке вопроса он назначает "foo" для foo и "bar" для bar.
8 ответов
Обычно это называется деструктурирующим связыванием в функциональных языках (у которых нет назначений) и деструктурирующим назначением в императивных языках.
Некоторые языки предоставляют подмножества этой функции, а затем называют ее чем-то другим. Например, в Python он работает с кортежами, списками или последовательностями и называетсяраспаковкой кортежей, распаковкойсписков или распаковкой последовательностей, в Ruby он работает с массивами (или объектами, которые можно преобразовать в массив) и называется параллельным присваиванием.
Разрушающая связь может стать произвольно сложной. Например, это (мнимое) связывание
[Integer(a), b, 2, c] = some_array
назначил бы первый элемент some_array
в a
второй элемент b
и четвертый элемент c
, но только если первый элемент Integer
третий элемент равен 2
и длина 4. Таким образом, это даже включает в себя некоторую условную логику.
Разрушение связывания - это подмножество более общего сопоставления с образцом, которое является стандартной функцией функциональных языков, таких как Haskell, ML, OCaml, F#, Erlang и Scala. Различие состоит в том, что деструктурирующее связывание позволяет только разбирать структуру и связывать ее компоненты с переменными, тогда как сопоставление с образцом также сопоставляет значения внутри этих структур и позволяет принимать решения, в частности позволяет запускать произвольный код в контексте связываний. (Вы можете видеть вышеописанное воображаемое связывание как середину между разрушающим связыванием и сопоставлением с образцом.)
Вот классический пример reverse
функция на воображаемом языке, написанная с использованием сопоставления с образцом:
def reverse(l: List): List {
match l {
when [] { return [] }
when [first :: rest] { return (reverse(rest) :: first) }
}
}
В Python он известен как распаковка списка или последовательности: http://docs.python.org/tutorial/datastructures.html
my_list = ["foo", "bar"]
foo, bar = my_list
Это называется параллельным присваиванием в Ruby и других языках.
Perl и PHP называют это списком
Perl:
my ($foo, $bar, $baz) = (1, 2, 3);
PHP:
list($foo, $bar, $baz) = array(1, 2, 3);
Mozilla называет это разрушительным назначением. В Python это распаковка последовательности; Распаковка кортежей - это частный частный случай.
В Erlang это... ну, это не назначение, это сопоставление с образцом (видя, что в Erlang нет назначения, как такового).
$ erl
Erlang R14B (erts-5.8.1) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:true]
Eshell V5.8.1 (abort with ^G)
1> [H1, H2, H3| Rest] = [1,2,3,4,5].
[1,2,3,4,5]
2> H1.
1
3> H2.
2
4> H3.
3
5> Rest.
[4,5]
Почему это называется "сопоставление с образцом"? Потому что это на самом деле соответствует шаблонам. Посмотрите:
6> [1,2,3,4,A] = [1,2,3,4,5].
[1,2,3,4,5]
7> A.
5
8> [1,2,3,4,A] = [1,2,3,4,6].
** exception error: no match of right hand side value [1,2,3,4,6]
В первом мы сделали то, что фактически означает утверждение, что список начнется с [1,2,3,4]
и что пятое значение может быть чем угодно, но, пожалуйста, свяжите его с несвязанной переменной A
, Во втором мы сделали то же самое, за исключением того, что A
теперь связан, поэтому мы явно ищем список [1,2,3,4,5]
(так как A
сейчас 5
).
В Clojure это называется разрушением. Простой пример:
(let [[foo bar] ["foo" "bar"]]
(println "I haz" foo "and" bar))
Он также часто используется в определениях функций, например, следующие разлагают единый точечный аргумент на компоненты x и y:
(defn distance-from-origin [[x y]]
(sqrt (+ (* x x) (* y y))))
Вы также можете использовать ту же технику для деструктурирования вложенных структур данных или ассоциативных карт ключ / значение.
Если вы рассматриваете правую часть как кортеж, можно рассматривать назначение как своего рода распаковку кортежей.