Mit Hintergrund aus Python / Java / Golang-Sprachen war das import
vs use
auch für mich verwirrt. Dies erklärt den Mechanismus der Wiederverwendung von Code anhand einiger Beispiele für deklarative Sprachen.
importieren
Kurz gesagt, in Elixir müssen Sie keine Module importieren. Auf alle öffentlichen Funktionen kann mit der vollqualifizierten Syntax MODULE.FUNCTION zugegriffen werden:
iex()> Integer.mod(5, 2)
1
iex()> String.trim(" Hello Elixir ")
"Hello Elixir"
In Python / Java / Golang müssen Sie, import MODULE
bevor Sie Funktionen in diesem MODUL verwenden können, z. B. Python
In []: import math
In []: math.sqrt(100)
Out[]: 10.0
Was import
in Elixir dann tut, könnte Sie überraschen:
Wir verwenden den Import immer dann, wenn wir problemlos auf Funktionen oder Makros anderer Module zugreifen möchten, ohne den vollständig qualifizierten Namen zu verwenden
https://elixir-lang.org/getting-started/alias-require-and-import.html#import
Also , wenn Sie möchten , geben Sie sqrt
statt Integer.sqrt
, trim
statt String.trim
, import
wird dazu beitragen ,
iex()> import Integer
Integer
iex()> sqrt(100)
10.0
iex()> import String
String
iex()> trim(" Hello Elixir ")
"Hello Elixir"
Dies kann zu Problemen beim Lesen von Code führen und wenn es zu Namenskonflikten kommt, wird dies in Erlang (der Sprache, die Elixir beeinflusst) nicht empfohlen . Aber es gibt keine solche Konvention in Elixir, Sie können sie auf eigenes Risiko verwenden.
In Python kann der gleiche Effekt erzielt werden durch:
from math import *
und es wird nur empfohlen, in einigen speziellen Szenarien / im interaktiven Modus zu verwenden - für kürzeres / schnelleres Tippen.
verwenden & benötigen
Was macht use
/ require
unterscheidet ist, dass sie sich auf "Makro" beziehen - das Konzept, das es in der Python / Java / Golang ... -Familie nicht gibt.
Sie benötigen kein import
Modul, um seine Funktionen zu verwenden, aber Sie benötigen require
ein Modul, um seine Makros zu verwenden :
iex()> Integer.mod(5, 3) # mod is a function
2
iex()> Integer.is_even(42)
** (CompileError) iex:3: you must require Integer before invoking the macro Integer.is_even/1
(elixir) src/elixir_dispatch.erl:97: :elixir_dispatch.dispatch_require/6
iex()> require Integer
Integer
iex()> Integer.is_even(42) # is_even is a macro
true
Obwohl is_even
es als normale Funktion geschrieben werden kann, ist es ein Makro, weil:
In Elixir ist Integer.is_odd / 1 als Makro definiert, damit es als Schutz verwendet werden kann.
https://elixir-lang.org/getting-started/alias-require-and-import.html#require
use
, Auszug aus Elixir doc:
Die Verwendung erfordert das angegebene Modul und ruft dann den __using__/1
Rückruf auf, sodass das Modul Code in den aktuellen Kontext einfügen kann.
defmodule Example do
use Feature, option: :value
end
wird kompiliert in
defmodule Example do
require Feature
Feature.__using__(option: :value)
end
https://elixir-lang.org/getting-started/alias-require-and-import.html#use
Schreiben use X
ist also dasselbe wie Schreiben
require X
X.__using__()
use/2
ist ein Makro , Makro wandelt Code in anderen Code für Sie um.
Sie werden wollen, use MODULE
wenn Sie:
- möchte auf seine Makros zugreifen (
require
)
- UND ausführen
MODULE.__using__()
Getestet mit Elixir 1.5
import Module
Bringt Funktionen ein, die in Ihrem Modul verwendet werden können.use Module
bringt Funktionen zur Verwendung und macht sie öffentlich auf Ihrem Modul