अमृत: आयात बनाम उपयोग


134

बीच क्या अंतर है useऔर import?

वर्तमान संदर्भ में दिए गए मॉड्यूल का उपयोग करने के लिए उपयोग एक सरल तंत्र है

https://hexdocs.pm/elixir/Kernel.SpecialForms.html#import/2

आयात और अन्य मॉड्यूल से मैक्रोज़

ऐसा लगता है कि एक अंतर यह है importकि आप विशिष्ट कार्यों / मैक्रो को बाहर निकालते हैं जबकि useसब कुछ अंदर लाता है।

क्या अन्य अंतर हैं? आप एक दूसरे का उपयोग कब करेंगे?


त्वरित सारांश: import Moduleअपने मॉड्यूल के अंदर उपयोग किए जाने वाले कार्यों में लाता है। use Moduleकार्यों में इस्तेमाल किया जा करने के लिए लाता है और उन्हें अपने मॉड्यूल पर सार्वजनिक रूप से उजागर करता है
येरेद

जवाबों:


213

import ModuleModuleअपने मॉड्यूल में संयुक्त राष्ट्र के नाम के सभी कार्य और मैक्रोज़ लाता है ।

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घ के रूप में ModAयह एक importबयान है कि में डाला गया था उत्पन्न किया ModB


6
बहुत बढ़िया जवाब! अधिक जानकारी के लिए: elixir-lang.org/getting-started/alias-require-and-import.html
justin

Elixir में हो रही है, और पायथन दुनिया से होने के नाते मैं थोड़े उलझन में हूँ कि मॉड्यूल *.exफ़ाइलों और defmoduleब्लॉकों के बारे में है, और आप फ़ाइल से मॉड्यूल को iex REPL
Nick T

2
उदाहरण / अवधारणा को समझने की कोशिश करना। इस विशेष मामले में आप केवल यह प्रदर्शित कर रहे हैं कि __using__विधि निष्पादित की गई है use ModA? यह शायद ModBआपके द्वारा सही प्रस्तुत किए गए उदाहरण में आयात का उपयोग करने के लिए समझ में आएगा ?
रयान-नील मेस

35

useवर्तमान मॉड्यूल में कोड इंजेक्ट करने के लिए अभिप्रेत है, जबकि importउपयोग के लिए अच्छी तरह से आयात कार्यों के लिए उपयोग किया जाता है। आप एक useकार्यान्वयन का निर्माण कर सकते हैं, जो उदाहरण के लिए स्वचालित रूप से फ़ंक्शंस का आयात करता है, जैसा कि मैं Timex के साथ करता हूं जब आप use Timexएक मॉड्यूल को जोड़ते हैं , तो timex.ex पर एक नज़र डालें यदि आप जानना चाहते हैं कि मेरा क्या मतलब है , तो यह एक बहुत ही सरल उदाहरण है कि कैसे निर्माण करें मॉड्यूल जो use'डी' हो सकता है


1
तो क्या यह कहना सही है कि useसामान्य से अधिक सामान्य है import? यही है, की कार्यक्षमता का importएक सबसेट हैuse
User314159

1
importयह अभी भी आवश्यक है, क्योंकि मुझे नहीं पता कि यह कहना सही है कि आप अकेले के importसाथ फिर से लागू कर सकते useहैं, लेकिन अगर यह संभव है तो मुझे आश्चर्य नहीं होगा। useहालांकि अधिक शक्तिशाली है। आप इसके साथ बहुत जटिल चीजें कर सकते हैं, उदाहरण के लिए, मैं useअपनी exprotobufपरियोजना में भारी उपयोग करता हूं जिसे आप देख सकते हैं कि क्या आप इसे सीमा तक धकेलना चाहते हैं। आप कोड के साथ मॉड्यूल का विस्तार कर सकते हैं, संकलन-समय पर कोड निष्पादित कर सकते हैं, मॉड्यूल में फ़ंक्शन जोड़ सकते हैं, आदि मूल रूप से यह जोड़ती है importऔर मैक्रोज़ की शक्ति।
बिटवॉकर

विस्तृत विवरण और कोड के संदर्भ के लिए धन्यवाद। मुझे लगता है मैं अब समझ गया। मैं अमृत के लिए अभी भी नया हूं, लेकिन मुझे लगता है कि एक बार मैं अधिक उपयोग-मामलों को देखूंगा तो मतभेद स्पष्ट होंगे।
User314159

अरे कोई बात नहीं, देखने के लिए एक और बढ़िया जगह फीनिक्स वेब फ्रेमवर्क होगा। क्रिस मैककॉर्ड ने अमृत मैक्रों पर एक किताब लिखी है, और वह फीनिक्स (सहित use) में उनका भारी उपयोग करता है । यह निश्चित रूप से एक शुरुआत के लिए के माध्यम से पढ़ने के लिए आसान हो सकता है exprotobuf, लेकिन मुझे लगता है कि मैं शायद useइसे सीमित करने के लिए धक्का देता हूं , exprotobufइसलिए यह उपयोगी हो सकता है कि आप इसे कितनी दूर ले जा सकते हैं।
बिटवल्कर

5
useवास्तव में बहुत कुछ नहीं करता है, यह केवल __using__निर्दिष्ट मॉड्यूल पर कॉल करता है।
पैट्रिक ऑस्सिटी

25

अमृत ​​के अधिकारी से «उर्फ, आवश्यकता और आयात» पृष्ठ देखें

# 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(arity 2 के साथ) से आयात कर रहे हैं List

ध्यान दें कि importएक मॉड्यूल को स्वचालित रूप से 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

14

पाइथन / जावा / गोलंग भाषाओं से पृष्ठभूमि के साथ, importबनाम useभी मेरे लिए भ्रमित था। यह कुछ घोषणा भाषाओं के साथ कोड पुन: उपयोग तंत्र की व्याख्या करेगा।

आयात

संक्षेप में, अमृत में, आपको मॉड्यूल आयात करने की आवश्यकता नहीं है। सभी सार्वजनिक कार्यों को पूर्ण-योग्य MODULE.FUNCTION सिंटैक्स द्वारा एक्सेस किया जा सकता है:

iex()> Integer.mod(5, 2)
1

iex()> String.trim(" Hello Elixir  ")
"Hello Elixir"

Python / Java / Golang में, import MODULEइससे पहले कि आप उस MODULE, जैसे Python में फ़ंक्शन का उपयोग कर सकें

In []: import math

In []: math.sqrt(100)
Out[]: 10.0

तब क्या importअमृत ​​में आपको आश्चर्य हो सकता है:

हम आयात का उपयोग तब करते हैं जब हम पूरी तरह से योग्य नाम का उपयोग किए बिना आसानी से अन्य मॉड्यूल से फ़ंक्शन या मैक्रोज़ तक पहुंचना चाहते हैं

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"

इससे कोड को पढ़ने में समस्या हो सकती है और जब नाम-विरोधाभास होता है, तो एर्लांग (एलिक्स को प्रभावित करने वाली भाषा) में इसकी सिफारिश नहीं की जाती है। लेकिन एलिक्ज़िर में ऐसा कोई सम्मेलन नहीं है, आप इसे स्वयं के जोखिम पर उपयोग कर सकते हैं।

पायथन में, एक ही प्रभाव द्वारा किया जा सकता है:

from math import * 

और यह केवल कुछ विशेष परिदृश्यों / इंटरैक्टिव मोड में उपयोग करने के लिए अनुशंसित है - छोटे / तेज टाइपिंग के लिए।

उपयोग और आवश्यकता है

क्या बनाता है use/ requireअलग है कि वे "मैक्रो" से संबंधित हैं - अवधारणा जो पायथन / जावा / गोलंग ... परिवार में मौजूद नहीं है।

आप की जरूरत नहीं है 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इसे एक सामान्य कार्य के रूप में लिखा जा सकता है, यह एक मैक्रो है क्योंकि:

अमृत ​​में, Integer.is_odd / 1 को एक मैक्रो के रूप में परिभाषित किया गया है ताकि इसे एक गार्ड के रूप में इस्तेमाल किया जा सके।

https://elixir-lang.org/getting-started/alias-require-and-import.html#require

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__()

एलिक्सिर 1.5 पर परीक्षण किया गया


3

use Module आवश्यकता है Module और __using__उस पर भी कॉल करें।

import Moduleवर्तमान संदर्भModule में कार्यक्षमता लाता है , न केवल इसकी आवश्यकता है।


0

आयात

लेक्सिकल स्कोप के अंदर सुलभ किसी दिए गए मॉड्यूल से सभी फंक्शंस और मैक्रोज़ बनाता है, जहां इसे कहा जाता है। ध्यान रखें कि ज्यादातर मामलों में आपको आयात किए जाने के लिए केवल एक या अधिक फ़ंक्शन / मैक्रो की आवश्यकता होती है।

उदाहरण:

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

वैसे, अमृत में अधिक निर्भरता से निपटने के निर्देश हैं

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.