2017-09-09 5 views
2

Im Buch „Programming Elixir“ Dave Thomas zeigt ein BeispielWie funktionieren Funktionen in Elixir?

handle_open = fn 
    {:ok, file} -> "Read data: #{IO.read(file, :line)}" 
    {_, error} -> "Error: #{:file.format_error(error)}" 
end 

handle_open.(File.open("code/intro/hello.exs")) 
handle_open.(File.open("nonexistent")) 

Ich kann nicht verstehen, warum zweiten Aufruf der Funktion in die zweite Strömung geht.

handle_open = fn(file) 

: auch, warum wir nicht ein Argument in func passieren?

Antwort

3

Dies ist eine anonyme Funktion mit mehreren Klauseln. handle_open hat 2 Klauseln, eine, um Argumente mit dem Muster {:ok, file} und eins mit {_, error} zu entsprechen. Das erste Muster, das den Argumenten entspricht, wird ausgeführt. Der angegebene Code ist fast [1] entspricht dem folgenden:

handle_open = fn arg -> 
    case arg do 
    {:ok, file} -> ... 
    {_, error} -> ... 
    end 
end 

Also, wenn die Datei vorhanden ist, File.open{:ok, file} zurückkehren und die erste Klausel ausgeführt wird. Wenn dies nicht der Fall ist, wird {:error, error} zurückgegeben, was der zweiten Klausel entspricht und diese ausführt.

[1]: "Fast", weil der Fehler, der auftritt, wenn keines der Muster übereinstimmt, in den beiden Fällen etwas anders ist.

+0

Dank! Ich bin ein bisschen damit beschäftigt ... –

0

Dies imitiert nur das Pattern-Match-Verhalten von Elixir.

Wie Sie Muster passen auf Ihre Module Funktionen auch haben können.

defmodule MyModule do 
    def read_file(path) do 
    File.open(path) |> handle_file() 
    end 

    defp handle_file({:ok, file}) do 
    // File there.. 
    end 

    defp handle_file({_, error}) do 
    // Could not open file.. because of `error` 
    end 
end 

Wie in dem Buch Beispiel würde ich versuchen, die Datei in einem Fall Klausel zu öffnen und das Ergebnis an der entsprechenden Funktion delegieren:

defmodule FileReader do 

    def read_file(path) do 
    case File.open(path) do 
     {:ok, file} -> handle_file(file) 
     {_, error} -> handle_error(error) 
    end 
    end 

    defp handle_file(file) do 
    // File there.. 
    end 

    defp handle_error(error) do 
    // 
    end 
end 
Verwandte Themen