2016-07-10 10 views
3

Kann jemand bitte helfen zu erklären, warum wir den Argumentfehler bekommen? Sollen wir nicht auf diese Weise auf Truthigkeit prüfen? Auf Elixir 1,3Elixir - Argument Fehler

iex(1)> true and true 
true 
iex(2)> "true" 
"true" 
iex(3)> true 
true 
iex(4)> true and "true" 
"true" 
iex(5)> "true" and true 
** (ArgumentError) argument error: "true" 

Antwort

3

Elixir hat zwei Sätze von Booleschen Operatoren:

  • or, and und not grundsätzlich ihre Argumente erfordern tatsächlichen booleans, dh die Atome true und false
  • ||, && und ! akzeptieren Argumente zu sein, alle Arten, und prüfen Sie "Wahrheit".

Obwohl in der Tat, or und and nur überprüfen Sie die Art des ersten Argument. Für jeden Wert von x werden die Ausdrücke false or x und true and x einfach x zurückgeben. Dies mag verwirrend erscheinen, erlaubt aber die Verwendung von or und and als letzten Ausdruck in einer rekursiven Funktion, ohne die Tail-Rekursion zu behindern.Betrachten wir zum Beispiel diese Funktion, die alle Elemente in einer Liste überprüft, ob auf 42 gleich sind:

def x([]) do 
    true 
end 
def x([h|t]) do 
    h == 42 and x(t) 
end 

Da and erlaubt Endrekursion, wird diese Funktion in konstanten Stapelspeicher laufen. Wenn and den Typ seines zweiten Arguments überprüfen würde, müsste die Funktion einen normalen Aufruf eines Stapelrahmens "tiefer" machen und bei der Rückkehr die Überprüfung durchführen und den Wert zurückgeben.

+0

Danke für die Erklärung nicht nur warum, sondern auch die Gründe dafür – sat

0

Aus der Dokumentation:

Elixir bietet auch drei Boolesche Operatoren: oder, und nicht. Diese Operatoren sind streng in dem Sinne, dass sie einen boolean (true oder false) als erstes Argument erwartet:

iex> true and true 
true 
iex> false or is_atom(:example) 
true 

eine nicht-boolean Bereitstellung wird eine Ausnahme ausgelöst:

iex> 1 and true 
** (ArgumentError) argument error: 1 

Das ist also zu beantworten, warum es ansteigt.

Um das zu tun, was Sie wollen, müssen Sie den && Operator verwenden, so wäre es

"true" && true 

wieder ein Zitat von der Dokumentation sein:

Neben diesen Booleschen Operatoren Elixir bietet auch ||, & & und! , die Argumente beliebigen Typs akzeptieren. Für diese Operatoren sind alle Werte außer falsch und Null wird auf true bewerten:

# and 
iex> nil && 13 
nil 
iex> true && 17 
17 
2

Die „wordy“ Boolesche Operatoren - and, or und not sind streng - sie erwarten, dass alle Werte streng boolean sein. Die symbolischen Operatoren - &&, || und ! - operieren auf der "Wahrhaftigkeit" statt auf strikten Booleschen Werten.

Da alle booleschen Operatoren kurzgeschlossen sind, werden sie nur das erste Argument auf streng Boolean überprüfen, aber ich rate davon ab, sie mit Nicht-Booleans zu verwenden.