2010-10-17 8 views
12

Мне нужно знать правильное имя для этой классной функции, которую предоставляют некоторые языки.Как называется функция [foo, bar] = ["foo", "bar"]?

FYI: На некоторых языках возможно выполнять множественные назначения путем присвоения структуры значений структуре «переменных». В примере в заголовке вопроса он присваивает «foo» foo и «bar» в bar.

+0

Прохладный особенность? В самом деле? Никогда не слышал об этом раньше, но я нахожу это только запутанным. Вскоре нам понадобятся некоторые инструменты, чтобы сделать код «программистом читаемым». – Damien

+8

@Damien: Ничего себе, способ слишком остро реагировать. –

+8

@ Damien: [blub] (http://www.paulgraham.com/avg.html) много? –

ответ

22

Это обычно называют деструктурирующий связывают в функциональных языках (которые не имеют) и назначение деструктурирования в императивных языках.

Некоторые языки предоставляют подмножества этой функции, а затем называют ее чем-то другим. Например, в Python работает с кортежей, списков или последовательностей и называется Tuple распаковке, Список распаковки или последовательности распаковка, в Ruby, он работает с массивами (или объектов, которые могут быть конвертированы в массив) и Параллельное назначение.

Деструктурирующее связывание может быть произвольно сложным. Например. это (мнимая) связывают

[Integer(a), b, 2, c] = some_array 

назначит первый элемент some_array к a, второй элемент к b и четвертый элемент к c, но только, если первый элемент является Integer, третий элемент равна 2, а длина равна 4. Таким образом, это даже включает некоторую условную логику.

Destructuring bind - это подмножество более общего назначения , соответствующее, которое является стандартной функцией функциональных языков, таких как Haskell, ML, OCaml, F #, Erlang и Scala. Разница заключается в том, что связывание destructuring позволяет только отделить структуру и привязать ее компоненты к переменным, тогда как соответствие шаблонов также соответствует значениям внутри этих структур и позволяет принимать решения и, в частности, позволяет запускать произвольный код в контексте привязок. (Вы можете видеть вышеупомянутое воображаемое связывание как на полпути между деструктурированием привязки и сопоставлением шаблонов.)

Вот классический пример reverse функции в воображаемом языке, написанной с использованием сопоставления с образцом:

def reverse(l: List): List { 
    match l { 
    when []    { return [] } 
    when [first :: rest] { return (reverse(rest) :: first) } 
    } 
} 
+0

Собственно, в Python он работает для любой последовательности. –

+0

@Matthew Flaschen: Спасибо. Я добавил * Sequence Unpacking * и опустил слово «только» из описания. –

+0

Я должен был быть более ясным как в моем ответе (обновленном), так и в комментариях. Кортежи и списки являются особыми типами последовательности в Python, поэтому распаковка и распаковка списка - это только особые случаи распаковки последовательности. –

2

Если вы рассматриваете правую сторону как кортеж, можно было бы просмотреть назначение как вид Tuple Unpacking.

4

Это называется параллельным присваивание в Ruby, и других языках.

3

Perl и PHP называют это назначение списка

Perl:

my ($foo, $bar, $baz) = (1, 2, 3); 

PHP:

list($foo, $bar, $baz) = array(1, 2, 3); 
2

В 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).

2

В Clojure это будет называться destructuring. Простой пример:

(let [[foo bar] ["foo" "bar"]] 
    (println "I haz" foo "and" bar)) 

Он также часто используется в определениях функций, например. следующее destructures один аргумента в точке х и у компонентов:

(defn distance-from-origin [[x y]] 
    (sqrt (+ (* x x) (* y y)))) 

Вы также можете использовать ту же технику, чтобы destructure вложенных структур данных или ключевые карт ассоциативных/значение.

 Смежные вопросы

  • Нет связанных вопросов^_^