2010-10-17 26 views
12

Muszę znać poprawną nazwę tej fajnej funkcji, którą zapewniają niektóre języki.Jaka jest nazwa funkcji [foo, bar] = ["foo", "bar"]?

FYI: W niektórych językach możliwe jest wykonywanie wielu przypisań poprzez przypisanie struktury wartości do struktury "zmiennych". W przykładzie w tytule pytania przypisuje "foo" do foo i "bar" do paska.

+0

Fajna funkcja? Naprawdę? Nigdy o tym nie słyszałem, ale uważam, że jest to tylko mylące. Wkrótce będziemy potrzebować narzędzi do kodowania "programisty czytelnego". – Damien

+8

@Damien: Wow, sposób na przesadny. –

+8

@Damien: [blub] (http://www.paulgraham.com/avg.html) dużo? –

Odpowiedz

22

Jest powszechnie nazywane rozpad wiążą w językach funkcjonalnych (których nie mają przypisania) i zadanie destrukturyzacji w językach imperatywnych.

Niektóre języki zapewniają podzbiory tej funkcji, a następnie nazywają ją czymś innym. Na przykład w Pythonie działa z krotki, listy lub sekwencji i nazywa krotka rozpakowaniu, Lista rozpakowaniu lub Sequence rozpakowywania w Ruby, współpracuje z tablicami (lub obiektów, które są wymienialne na tablicy) i jest o nazwie przypisanie równoległe.

Wiązanie destruktury może być dowolnie złożone. Na przykład. Ten (urojona) wiążą

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

przypisze pierwszy element some_array do a, drugi element do b i czwarty element do c, ale tylko jeżeli pierwszy element jest Integer trzeci element ma równa się 2, a długość wynosi 4. Tak więc zawiera nawet pewną logikę warunkową.

Wiązanie destruktury jest podzbiorem bardziej ogólnego wzoru dopasowanego do, który jest standardową cechą języków funkcjonalnych, takich jak Haskell, ML, OCaml, F #, Erlang i Scala. Różnica polega na tym, że destrukturyzacja pozwala tylko rozebrać strukturę i powiązać jej komponenty ze zmiennymi, podczas gdy dopasowywanie wzorców dopasowuje się również do wartości wewnątrz tych struktur i pozwala podejmować decyzje, a w szczególności umożliwia uruchamianie dowolnego kodu w kontekście powiązań. (Powyższe wyimaginowane wiązanie można zobaczyć w połowie konfliktu destruktury i dopasowywania wzorca.)

Oto klasyczny przykład reverse funkcji w języku wyimaginowanej, napisane przy użyciu dopasowania wzoru:

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

W rzeczywistości w Pythonie działa on w dowolnej kolejności. –

+0

@Matthew Flaschen: Dzięki. Dodałem * Rozpakowywanie sekwencji * i usunąłem słowo "tylko" z opisu. –

+0

Powinienem być bardziej przejrzysty zarówno w mojej odpowiedzi (zaktualizowanej) i komentarz. Krotki i listy są szczególnymi rodzajami sekwencji w Pythonie, więc rozpakowywanie i rozpakowywanie list są tylko specjalnymi przypadkami rozpakowywania sekwencji. –

2

Jeśli widzisz po prawej stronie jako krotkę, można wyświetlić przypisanie jako rodzaj Tuple Unpacking.

4

To się nazywa zadanie równolegle w Ruby i innych językach.

3

Perl i PHP nazwać zadanie lista

Perl:

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

PHP:

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

W Erlang to ... cóż, to nie jest zadanie, to dopasowywanie wzorca (widząc, jak tam jest bez przydziału, jako takiego, w 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] 

Dlaczego jest nazywany "dopasowywaniem wzorców"? Ponieważ w rzeczywistości jest to dopasowanie wzorców. Spójrz:

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] 

W pierwszym z nich zrobiliśmy co skutecznie sprowadza się do twierdzenia, że ​​lista będzie zacząć [1,2,3,4] i że wartość piąty może być cokolwiek, ale należy powiązać go do niezwiązanej zmiennej A. W drugim zrobiliśmy to samo, z tym wyjątkiem, że A jest teraz powiązany, więc szukamy wyraźnie listy [1,2,3,4,5] (ponieważ A jest teraz 5).

2

W Clojure będzie to nazywane destructuring. Prosty przykład:

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

Jest również często używany w definicjach funkcji, np. następujące destructures jednego punktu do argumentu x i y składników:

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

Można również użyć tej samej techniki, aby destructure zagnieżdżone struktury danych lub podstawowe mapy asocjacyjne/wartość.

Powiązane problemy