34

Derzeit versuchen, den "^" Operator in Elixir zu verstehen. Von der Website:Was ist der "Pin" -Operator für, und sind Elixir-Variablen veränderbar?

Der Stift Operator^kann verwendet werden, wenn kein Interesse an Rebinding es eine Variable ist, sondern gegen ihren Wert vor dem Spiel in passenden:

Quelle - http://elixir-lang.org/getting_started/4.html

Vor diesem Hintergrund kann man wie so einen neuen Wert zu einem Symbol anhängen:

iex> x = 1 # Outputs "1" 
iex> x = 2 # Outputs "2" 

Ich kann auch tun:

iex> x = x + 1 # Outputs "3"! 

Also meine erste Frage ist; Sind Elixir-Variablen veränderbar? Sieht sicher so aus, wenn das der Fall ist ... Sollte das in einer funktionalen Programmiersprache nicht möglich sein?

So, jetzt kommen wir zum „^“ Operator ...

iex> x = 1 # Outputs "1" 
iex> x = 2 # Outputs "2" 
iex> x = 1 # Outputs "1" 
iex> ^x = 2 # "MatchError" 
iex> ^x = 1 # Outputs "1" 

Ich denke, die Wirkung von „^“ ist „x“ auf den letzten Wert zu sperren, um es binded. Ist das alles da? Warum nicht nur sicherstellen, dass alle "Übereinstimmungen"/Zuweisungen unveränderlich sind wie Erlang selbst?

Ich war nur, dass Gewöhnung ...

+2

Es ist nur nach Neuzuweisung beschattet. Daten sind immer noch unveränderbar. Das Schlussbeispiel aus [Joe Armstrongs Blog] (http://joearms.github.io/2013/05/31/a-week-with-elixir.html) sollte klarstellen. Meiner Meinung nach ist es verwirrend. –

+0

Ich denke, irgendwann müssen wir etwas zu den Elixir-Dokumenten hinzufügen, um dies zu erklären, da diese Frage regelmäßig gestellt wird. –

+2

Ich verstehe, dass der Operator^erforderlich ist, um eine Musterübereinstimmung und eine Zuweisung auf der linken Seite durchführen zu können. Was mir wirklich nicht klar ist, ist, warum das Standardverhalten "Shadowing/Re-Assigning" ist und nicht das Pattern Matching: - In meinem Code brauche ich wirklich nur sehr selten eine Neuzuweisung; - In einem Code, der behauptet, unveränderliche Daten zu haben, würde ich erwarten, dass die Neuzuweisung explizit ist. – Pascal

Antwort

45

Die Daten in Elixir ist noch unveränderlich, aber es gibt einige Kürzel, die Sie weniger lassen geben oder keine Sorge über neue Namen zu finden. sehen in Erlang, könnte man oft Code wie folgt:

SortedList = sort(List), 
FilteredList = filter(SortedList), 
List3 = do_something_with(FilteredList), 
List4 = another_thing_with(List3) 

In Elixir, man konnte nur schreiben:

list = sort(list) 
list = filter(list) 
list = do_something_with(list) 
list = another_thing_with(list) 

Dies ist genau das gleiche, aber es sieht ein wenig besser. Natürlich sind die besten Lösungen wie diese zu schreiben wäre:

list |> sort |> filter |> do_something |> another_thing_with 

Jedes Mal, Sie neue Sache zu list Variablen zuweisen, erhalten Sie neue Instanz:

iex(1)> a = 1 
1 
iex(2)> b = [a, 2] 
[1, 2] 
iex(3)> a = 2 
2 
iex(4)> b 
[1, 2] # first a did not change, it is immutable, currently a just points to something else 

Sie sagen nur, dass Sie nicht sind länger interessiert an der alten a und lassen Sie es auf etwas anderes zeigen. Wenn Sie aus dem Erlang-Hintergrund kommen, kennen Sie wahrscheinlich die Funktion f von der Shell.

A = 1. 
f(A). 
A = 2. 

In Elixir Sie nur müssen nicht den f schreiben. Es wird automatisch für Sie gemacht. Dies bedeutet, dass Sie jedes Mal, wenn Sie auf der linken Seite der Musterübereinstimmung eine Variable haben, diesem einen neuen Wert zuweisen.

Ohne den Operator ^ wäre es nicht möglich, eine Variable auf der linken Seite der Musterübereinstimmung zu haben, da sie von der rechten Seite einen neuen Wert erhalten würde.^ bedeutet, dass dieser Variable keine neuen Dinge zuweisen - behandeln Sie sie als Literalwert.

Deshalb ist in Elixir

x = 1 
[1, x, 3] = [1, 2, 3] 

entspricht in Erlang zu:

X = 1, 
[1, CompletelyNewVariableName, 3] = [1, 2, 3] 

und:

x = 1 
[1, ^x, 3] = [1, 2, 3] 

entspricht:

x = 1 
[1, 1, 3] = [1, 2, 3] 

, die in Erlang ist:

X = 1, 
[1, X, 3] = [1, 2, 3] 
+0

Ich würde lieber sagen 'x = 1; [1, x, 3] = [1, 2, 3] 'entspricht in Erlang folgendem:' X = 1. f (X). [1, X, 3] = [1, 2, 3] ' –

+2

In der Shell - ja, aber Sie können das auch in Skripten verwenden, wo' f/1' nicht möglich ist, deshalb habe ich es mit dem Erstellen verglichen neue Variable – tkowal

19

Daten in Elixier ist unveränderlich, Variablen obwohl sind neu zuordenbar. Was das Elixier leicht verwirrend machen kann, ist die kombinierte Zuordnung und Mustererkennung, die Sie sehen.

Wenn Sie das Gleichheitszeichen mit einer Variablenreferenz auf dem linken Elixier verwenden, stimmt das Muster zuerst mit der Struktur überein und führt dann eine Zuweisung aus. Wenn Sie nur eine einzige auf der linken variablen Referenz haben, wird es jede Struktur passen und wird so wie so zugewiesen werden:

a = 1 # 'a' now equals 1 
a = [1,2,3,4] # 'a' now equals [1,2,3,4] 
a = %{:what => "ever"} # 'a' now equals %{:what => "ever"} 

Wenn Sie eine komplexere Struktur auf der linken Elixier haben erste Muster der Strukturen übereinstimmen, dann führe die Aufgabe aus.

[1, a, 3] = [1,2,3] 
# 'a' now equals 2 because the structures match 
[1, a] = [1,2,3] 
# **(MatchError)** because the structures are incongruent. 
# 'a' still equals it's previous value 

Wenn Sie Match Wert gegenüber dem Inhalt einer Variablen Sie den Stift verwenden können ‚^‘:

a = [1,2] # 'a' now equals [1,2] 
%{:key => ^a} = %{:key => [1,2]} # pattern match successful, a still equals [1,2] 
%{:key => ^a} = %{:key => [3,4]} # **(MatchError)** 

Das erfundene Beispiel auch mit ‚a‘ auf der rechten Seite geschrieben worden sein könnte Seite und ohne den Stift:

%{:key => [1,2]} = %{:key => a} 

Jetzt sagen Sie eine Variable Teil einer Struktur zuweisen wollte, aber nur dann, wenn ein Teil dieser Struktur angepasst etwas gespeichert in ‚a‘, in Elixier diese trivial ist:

a = %{:from => "greg"} 
[message, ^a] = ["Hello", %{:from => "greg"}] # 'message' equals "Hello" 
[message, ^a] = ["Hello", %{:from => "notgreg"}] # **(MatchError)** 

In diesen einfachen Beispielen die Verwendung des Stiftes und Musterabgleich ist nicht sofort Super wertvoll, aber wie Sie mehr Elixier lernen und beginnen Muster mehr und mehr passende wird es Teil der Ausdruckskraft, dass Elixier bietet.

+0

beste Antwort! - geh greg – metakungfu