Ich habe eine allgemeine Frage zu Standardparametern und Nullwerten. Angenommen, ich habe zwei Funktionen. Man ruft den anderen an (was eine Hilfsfunktion ist). Beide haben einen optionalen Parameter.Elixier: Wie geht man mit optionalen/Standard-Parameter in Funktionen und Nullwerte?
Die Hilfsfunktion verbindet nur eine Liste mit einer Zeichenfolge mit einem Verbinder. Der Verbinder wird an die erste Funktion in einer opts-Schlüsselwortliste übergeben. Die Weitergabe des Tischlers ist optional, wird standardmäßig "AND"
defmodule ParamTest do
def func_1(list, opts \\ []) do
helper(list, opts[:joiner])
# Do something else with the result
end
defp helper(list, joiner \\ "AND") do
Enum.join(list, " #{joiner} ")
end
end
# Example 1
["el 1", "el 2"]
|> ParamTest.func_1(joiner: "AND")
# Result "el 1 AND el 2"
# Example 2
["el 1", "el 2"]
|> ParamTest.func_1
# Result: "el 1 el 2"
# But it should be also "el 1 AND el 2"
Das Problem ist: opts [: Schreiner] nil im zweiten Beispiel sein wird. Aber es ist immer noch vorhanden, so dass der Standardwert nicht verwendet wird.
Eine mögliche Lösung wäre die Verwendung case
:
defmodule ParamTest do
def func_1(list, opts \\ []) do
case is_nil(opts[:joiner]) do
true -> helper(list)
false -> helper(list, opts[:joiner])
end
# Do something else with the result
end
defp helper(list, joiner \\ "AND") do
Enum.join(list, " #{joiner} ")
end
end
Ein anderer Weg wäre für Helfer zwei Funktionsdefinitionen zu verwenden und Musterabgleich verwenden:
defmodule ParamTest do
def func_1(list, opts \\ []) do
case is_nil(opts[:joiner]) do
true -> helper(list)
false -> helper(list, opts[:joiner])
end
end
defp helper(list, nil) do
Enum.join(list, " AND ")
end
defp helper(list, joiner \\ "AND") do
Enum.join(list, " #{joiner} ")
end
end
Aber ich habe das Gefühl, dass diese ist nicht sehr elegant und könnte in komplexeren Situationen unordentlich werden.
Was ist eine bessere Lösung für dieses Szenario?
Ich stimme dem Standardargument für private Funktionen zu. Und ich mag deine zweite Lösung. Vielen Dank. –
Wenn der Helfer nur von der ersten Funktion aus aufgerufen wird, dann ist die doppelte Vorgabe peinlich. Die zweite Lösung ist peinlich, weil Sie die || haben innerhalb des Funktionsaufrufs. Sie sind besser dran, nur mit Ihrem Standard sein opts \\ [joiner: "UND"] – CaptChrisD
@CaptChrisD wie andere Leute in den Kommentaren auf die andere Funktion hingewiesen, '[joiner:" UND "]' als Standard * in der Regel * ist keine gute Idee, da die Funktion viele Optionen akzeptieren kann (es ist selten, dass eine Funktion nur eine Option akzeptiert). – whatyouhide