Эликсир: использование против импорта



В чем разница между use и import?




использовать простой механизм для использования данного модуля в современных условиях




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




импорт функции и макросы из других модулей




похоже, одна разница import давайте вы выберете конкретные функции / макросы, тогда как use приносит все в.



есть ли другие различия? Когда следует использовать один над другим?

386   5  

5 ответов:

import Module приносит все функции и макросы Module un-namespaced в ваш модуль.

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

когда вы used ModA она вызвала import оператор, который был вставлен в ModB.

use предназначен для ввода кода в текущий модуль, в то время как import используется для импорта функций для использования. Вы можете построить use реализация, которая автоматически импортирует функции, например, как я делаю с Timex, когда вы добавить use Timex в модуле взгляните на timex.Ex если вы хотите знать, что я имею в виду, это очень простой пример того, как создать модуль, который может быть use ' d

посмотреть "псевдоним, требовать, и импорт" страница из официального руководства по началу работы elixir:

# 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 предоставляет макросы как механизм для мета-программирования (написания кода, который генерирует код).

макросы-это фрагменты кода, которые выполняются и расширяются во время компиляции. Это означает, что для того, чтобы использовать макрос, мы должны гарантировать, что его модуль и реализация доступны во время компиляции. Это покончено с

с фоном из языков Python / Java / Golang,import vs use был также смущен для меня. Это объяснит механизм повторного использования кода с некоторыми примерами декларативных языков.

импорт

короче говоря, в Elixir вам не нужно импортировать модули. Все публичные функции могут быть доступны с помощью полнофункционального модуля.Синтаксис функции:

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

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

в Python / Java / Golang, вам нужно import MODULE прежде чем вы сможете использовать функции в этом модуле, например Питон

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"

это может вызвать проблемы для чтения кода и когда есть имя-конфликтующие так это не рекомендуется на Erlang (язык, который влияет на Эликсир). Но в Эликсире нет такой условности, вы можете использовать его на свой страх и риск.

в 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 может быть записана как обычная функция, это макрос, потому что:

В Эликсир, Целое число.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

так писать!--24--> это то же самое, что писать

require X
X.__using__()

use/2макрос, макрос преобразует код в другой код для вас.

вы хотите use MODULE если вы:

  • хотите получить доступ к его макросам (require)
  • и выполнить MODULE.__using__()

Испытано на Эликсире 1.5

use ModuleтребуетModule, а также __using__ на нем.

import Module выводит Module функциональность текущий контекст, а не просто требует этого.

Comments

    Ничего не найдено.