違いは何だuse
とはimport
?
使用は、特定のモジュールを現在のコンテキストで使用するための単純なメカニズムです。
https://hexdocs.pm/elixir/Kernel.SpecialForms.html#import/2
他のモジュールから関数とマクロをインポートします
1つの違いはimport
、特定の関数/マクロを選択するのに対して、use
すべてを導入することです。
他に違いはありますか?いつどちらを使用しますか?
違いは何だuse
とはimport
?
使用は、特定のモジュールを現在のコンテキストで使用するための単純なメカニズムです。
https://hexdocs.pm/elixir/Kernel.SpecialForms.html#import/2
他のモジュールから関数とマクロをインポートします
1つの違いはimport
、特定の関数/マクロを選択するのに対して、use
すべてを導入することです。
他に違いはありますか?いつどちらを使用しますか?
回答:
import Module
Module
名前空間のないすべての関数とマクロをモジュールに取り込みます。
require Module
のマクロを使用できますModule
が、インポートはされません。(の関数はModule
、常に名前空間を使用できます。)
use Module
最初のrequires
モジュール、次に__using__
マクロを呼び出しますModule
。
以下を検討してください。
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
。
*.ex
のファイルとdefmodule
ブロックを、そしてどのようにIEX REPLにファイルからモジュールを引くだろう
__using__
メソッドがuse ModA
?で実行されることを示しているだけです。ModB
あなたが正しいものを提示した例では単にインポートを使用することはおそらく意味がありますか?
use
現在のモジュールにコードを挿入することを目的としていますが、import
使用する関数をインポートするためにも使用されます。use
たとえば、use Timex
モジュールを追加するときにTimexで行うように、関数を自動的にインポートする実装を構築できます。意味を知りたい場合は、timex.exを参照してください。これは、することができ、モジュールuse
D」
use
より一般的であると言うのは正確import
ですか?つまり、の機能import
は次のサブセットですuse
import
私はそれはあなたが再実装することができますと言って正確かどうかわからないよう、依然として必要であるimport
とuse
だけではなく、それが可能だ場合、私は驚かないだろう。use
絶対にもっと強力です。あなたはそれで非常に複雑なことをすることができます、例えば、私use
は自分のexprotobuf
プロジェクトで頻繁に使用しています。モジュールをコードで拡張したり、コンパイル時にコードを実行したり、関数をモジュールに追加したりすることができます。基本的に、それimport
はマクロの能力と結合します。
use
)で頻繁に使用しています。ほぼ間違いなく初心者の方が読みやすくなりますがexprotobuf
、use
限界に達してexprotobuf
いると思うので、どれだけ遠くまで行けるかを確認するだけでも役立つでしょう。
use
実際にはあまり機能せず、__using__
指定されたモジュールを呼び出すだけです。
参照してください«エイリアスを必要とし、輸入»エリクシルの公式からページスタートガイド:
# 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
完全修飾名を使用せずに、他のモジュールから関数またはマクロに簡単にアクセスしたい場合はいつでも使用します。たとえばduplicate/2
、List
モジュールの関数を数回使用したい場合は、それをインポートできます。
iex> import List, only: [duplicate: 2]
List
iex> duplicate :ok, 3
[:ok, :ok, :ok]
この場合、から関数duplicate
(アリティ2)のみをインポートしていList
ます。
import
モジュールを使用すると、自動的に使用されることに注意してくださいrequire
。
ディレクティブで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
vs 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
次にimport
、Elixirで何があなたを驚かせるでしょう:
完全修飾名を使用せずに他のモジュールから関数またはマクロに簡単にアクセスしたい場合は常にインポートを使用します
https://elixir-lang.org/getting-started/alias-require-and-import.html#import
だから、あなたが入力したい場合はsqrt
代わりにInteger.sqrt
、trim
代わりのString.trim
、import
意志のヘルプ
iex()> import Integer
Integer
iex()> sqrt(100)
10.0
iex()> import String
String
iex()> trim(" Hello Elixir ")
"Hello Elixir"
これはコードの読み取りで問題を引き起こす可能性があり、名前が競合する場合、Erlang(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からの抜粋:
使用するには、指定されたモジュールが必要であり、そのモジュールの
__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でテスト済み
指定されたモジュールのすべての関数とマクロを、それが呼び出されるレキシカルスコープ内でアクセスできるようにします。ほとんどの場合、インポートする必要があるのは1つ以上の関数/マクロのみであることに注意してください。
例:
defmodule TextPrinter do
import IO, only: [puts: 1]
def execute(text) do
puts(text)
end
end
iex> TextPrinter.execute("Hello")
Hello
:ok
このマクロを使用すると、現在のモジュールに任意のコードを挿入できます。で外部ライブラリを使用するときは注意が必要ですuse
です。裏で正確に何が行われているのかわからない場合があるためです。
例:
defmodule Printer do
defmacro __using__(_opts) do
quote do
def execute(text) do
IO.puts(text)
end
end
end
end
defmodule TextPrinter do
use Printer
end
iex> TextPrinter.execute("Hello")
Hello
:ok
内部のシーンコードの裏側 __using__
にTextPrinter
モジュールに挿入されています。
import Module
モジュール内で使用される関数を取り込みます。use Module
使用する関数を