use
とimport
の違いは何ですか?
useは、指定されたモジュールを現在のコンテキストに使用するためのシンプルなメカニズムです
https://hexdocs.pm/elixir/Kernel.SpecialForms.html#import/2
他のモジュールから関数とマクロをインポートします
1つの違いはimport
のように見えますが、use
はすべてを取り込むのに対して、特定の関数/マクロを選択できます。
他に違いはありますか?いつ他を使用しますか?
_import Module
_は、Module
のすべての関数とマクロを名前空間なしでモジュールに取り込みます。
_require Module
_では、Module
のマクロを使用できますが、インポートはしません。 (Module
の関数は常に名前空間付きで利用可能です。)
_use Module
_最初にrequires
モジュールを実行し、Module
で___using__
_マクロを呼び出します。
以下を考慮してください。
_defmodule ModA do
defmacro __using__(_opts) do
IO.puts "You are USING ModA"
end
def moda() do
IO.puts "Inside ModA"
end
end
defmodule ModB do
use ModA
def modb() do
IO.puts "Inside ModB"
moda() # <- ModA was not imported, this function doesn't exist
end
end
_
ModA.moda()
がModB
にインポートされていないため、これはコンパイルされません。
ただし、以下はコンパイルされます。
_defmodule ModA do
defmacro __using__(_opts) do
IO.puts "You are USING ModA"
quote do # <--
import ModA # <--
end # <--
end
def moda() do
IO.puts "Inside ModA"
end
end
defmodule ModB do
use ModA
def modb() do
IO.puts "Inside ModB"
moda() # <-- all good now
end
end
_
use
d ModA
の場合と同様に、import
に挿入されたModB
ステートメントを生成しました。
use
は現在のモジュールにコードを挿入するためのもので、import
は使用する関数をインポートするために使用されます。たとえば、Timexでモジュールにuse Timex
を追加するときと同様に、関数を自動的にインポートするuse
実装を構築できます 。timexを見てください。 ex私が何を意味するのか知りたい場合 、それはuse
'dになり得るモジュールを構築する方法の非常に簡単な例です
"alias、require、and import" エリクサーの公式スタートガイドのページをご覧ください:
# Ensure the module is compiled and available (usually for macros)
require Foo
# Import functions from Foo so they can be called without the `Foo.` prefix
import Foo
# Invokes the custom code defined in Foo as an extension point
use Foo
Elixirは、メタプログラミング(コードを生成するコードの記述)のメカニズムとしてマクロを提供します。
マクロは、コンパイル時に実行および展開されるコードの塊です。つまり、マクロを使用するには、コンパイル中にそのモジュールと実装が使用可能であることを保証する必要があります。これはrequire
ディレクティブで行われます。
一般に、そのモジュールで利用可能なマクロを使用したい場合を除いて、モジュールを使用する前に必要とする必要はありません。
完全修飾名を使用せずに、他のモジュールの関数またはマクロに簡単にアクセスする場合は常に、import
を使用します。たとえば、List
モジュールのduplicate/2
関数を数回使用する場合、インポートできます。
iex> import List, only: [duplicate: 2]
List
iex> duplicate :ok, 3
[:ok, :ok, :ok]
この場合、duplicate
から関数List
(アリティ2)のみをインポートしています。
モジュールを自動的にimport
ing require
sすることに注意してください。
ディレクティブではありませんが、use
はrequire
と密接に関連するマクロであり、現在のコンテキストでモジュールを使用できます。 use
マクロは、開発者が外部機能を現在の字句スコープ(多くの場合モジュール)に取り込むために頻繁に使用されます。
舞台裏では、use
は指定されたモジュールを必要とし、そのモジュールで__using__/1
コールバックを呼び出して、モジュールが現在のコンテキストにコードを挿入できるようにします。一般的に、次のモジュール:
defmodule Example do
use Feature, option: :value
end
にコンパイルされます
defmodule Example do
require Feature
Feature.__using__(option: :value)
end
Python/Java/Golang言語のバックグラウンドで、import
対use
も混乱していました。これは、いくつかの宣言型言語の例でコード再利用メカニズムを説明します。
つまり、Elixirでは、モジュールをインポートする必要はありません。すべてのパブリック関数には、完全修飾されたMODULE.FUNCTION構文を使用してアクセスできます。
_iex()> Integer.mod(5, 2)
1
iex()> String.trim(" Hello Elixir ")
"Hello Elixir"
_
Python/Java/Golangでは、そのモジュールで関数を使用する前に_import MODULE
_する必要があります、例えばPython
_In []: import math
In []: math.sqrt(100)
Out[]: 10.0
_
それから、Elixirのimport
はあなたを驚かせるかもしれません:
完全修飾名を使用せずに、他のモジュールから関数またはマクロに簡単にアクセスする場合は常にインポートを使用します
https://elixir-lang.org/getting-started/alias-require-and-import.html#import
したがって、_Integer.sqrt
_の代わりにsqrt
と入力したい場合、_String.trim
_の代わりにtrim
を入力すると、import
が役立ちます。
_iex()> import Integer
Integer
iex()> sqrt(100)
10.0
iex()> import String
String
iex()> trim(" Hello Elixir ")
"Hello Elixir"
_
これにより、コードの読み取りに問題が発生する可能性があり、名前の競合があるため、Erlang(Elixirに影響を与える言語)で 非推奨 になります。しかし、Elixirにはそのような規則はありません。独自のリスクで使用できます。
Pythonでは、次の方法で同じ効果を実現できます。
_from math import *
_
そして、 一部の特別なシナリオでは /インタラクティブモード-短い/速いタイピングのためにのみ使用することをお勧めします。
use
/require
が異なるのは、それらが「マクロ」に関連していることです。これは、Python/Java/Golang ...ファミリーには存在しない概念です。
関数を使用するためにモジュールをimport
する必要はありませんが、マクロを使用するためにモジュールをrequire
する必要があります:
_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
_
_is_even
_は通常の関数として記述できますが、次の理由によりマクロです。
Elixirでは、Integer.is_odd/1はマクロとして定義されているため、ガードとして使用できます。
https://elixir-lang.org/getting-started/alias-require-and-import.html#require
use
、Elixir docからの抜粋:
useは指定されたモジュールを必要とし、それから_
__using__/1
_コールバックを呼び出して、モジュールが現在のコンテキストにコードを挿入できるようにします。
_defmodule Example do
use Feature, option: :value
end
_
にコンパイルされます
_defmodule Example do
require Feature
Feature.__using__(option: :value)
end
_
https://elixir-lang.org/getting-started/alias-require-and-import.html#use
したがって、_use X
_を書くことは、書くことと同じです。
_require X
X.__using__()
_
_use/2
_ マクロです 、マクロはコードを他のコードに変換します。
次の場合は_use MODULE
_になります。
require
)MODULE.__using__()
を実行しますElixir 1.5でテスト済み
use Module
requiresModule
また、その上で__using__
を呼び出します。
import Module
は、必要なだけでなく、Module
機能を現在のコンテキストにもたらします。