Avec l'expérience des langages Python / Java / Golang, le import
vs use
était également confus pour moi. Cela expliquera le mécanisme de réutilisation du code avec quelques exemples de langages déclaratifs.
importer
En bref, dans Elixir, vous n'avez pas besoin d'importer de modules. Toutes les fonctions publiques sont accessibles par la syntaxe complète MODULE.FUNCTION:
iex()> Integer.mod(5, 2)
1
iex()> String.trim(" Hello Elixir ")
"Hello Elixir"
En Python / Java / Golang, vous devez import MODULE
avant de pouvoir utiliser des fonctions dans ce MODULE, par exemple Python
In []: import math
In []: math.sqrt(100)
Out[]: 10.0
Alors ce que fait import
Elixir pourrait vous surprendre:
Nous utilisons l'importation chaque fois que nous voulons accéder facilement aux fonctions ou aux macros d'autres modules sans utiliser le nom complet
https://elixir-lang.org/getting-started/alias-require-and-import.html#import
Donc, si vous voulez taper sqrt
au lieu de Integer.sqrt
, trim
au lieu de String.trim
, import
cela vous aidera
iex()> import Integer
Integer
iex()> sqrt(100)
10.0
iex()> import String
String
iex()> trim(" Hello Elixir ")
"Hello Elixir"
Cela peut poser des problèmes pour la lecture du code et en cas de conflit de nom, ce n'est donc pas recommandé dans Erlang (le langage qui influence Elixir). Mais il n'y a pas de telle convention dans Elixir, vous pouvez l'utiliser à vos risques et périls.
En Python, le même effet peut être fait par:
from math import *
et il n'est recommandé de l'utiliser que dans certains scénarios spéciaux / mode interactif - pour une saisie plus courte / plus rapide.
utiliser et exiger
Ce qui rend use
/ require
différent, c'est qu'ils se rapportent à "macro" - le concept qui n'existe pas dans la famille Python / Java / Golang ....
Vous n'avez pas besoin d' import
un module pour utiliser ses fonctions, mais vous avez besoin d' require
un module pour utiliser ses macros :
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
Bien que cela is_even
puisse être écrit comme une fonction normale, il s'agit d'une macro car:
Dans Elixir, Integer.is_odd / 1 est défini comme une macro afin de pouvoir être utilisé comme garde.
https://elixir-lang.org/getting-started/alias-require-and-import.html#require
use
, extrait de Elixir doc:
use requiert le module donné et appelle ensuite le __using__/1
rappel sur celui-ci permettant au module d'injecter du code dans le contexte actuel.
defmodule Example do
use Feature, option: :value
end
est compilé dans
defmodule Example do
require Feature
Feature.__using__(option: :value)
end
https://elixir-lang.org/getting-started/alias-require-and-import.html#use
Donc l'écriture use X
est la même chose que l'écriture
require X
X.__using__()
use/2
est une macro , la macro transformera le code en un autre code pour vous.
Vous voudrez use MODULE
quand vous:
- voulez accéder à ses macros (
require
)
- ET exécuter
MODULE.__using__()
Testé sur Elixir 1.5
import Module
apporte des fonctions à utiliser dans votre module.use Module
apporte des fonctions à utiliser ET les expose publiquement sur votre module