vida tutorial también sinonimo programación lenguaje inmortal framework buscó elixir

tutorial - elixir también se buscó



Elixir: uso vs importación (6)

¿Cuál es la diferencia entre use e import ?

El uso es un mecanismo simple para usar un módulo dado en el contexto actual

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

Importa funciones y macros de otros módulos

Parece que una diferencia es import permite elegir las funciones / macros específicas, mientras que el use lo incorpora todo.

¿Hay otras diferencias? ¿Cuándo usarías uno sobre el otro?


Importar

Hace que todas las funciones y macros de un módulo dado sean accesibles dentro del ámbito léxico donde se llama. Tenga en cuenta que, en la mayoría de los casos, solo necesita importar una o más funciones / macros.

Ejemplo:

defmodule TextPrinter do import IO, only: [puts: 1] def execute(text) do puts(text) end end iex> TextPrinter.execute("Hello") Hello :ok

Utilizar

Esta macro le permite inyectar cualquier código en el módulo actual. Debe tener cuidado al usar bibliotecas externas con el use , ya que es posible que no esté seguro de lo que sucede exactamente detrás de escena.

Ejemplo:

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

El código detrás de la escena dentro de __using__ se ha inyectado en el módulo TextPrinter .

Por cierto, hay más instrucciones de manejo de dependencias en Elixir .


Con antecedentes de los lenguajes Python / Java / Golang, la import vs use también fue confusa para mí. Esto explicará el mecanismo de reutilización de código con algunos ejemplos de lenguajes declarativos.

importar

En resumen, en Elixir, no necesita importar módulos. Se puede acceder a todas las funciones públicas mediante la sintaxis MODULE.FUNCTION completa:

iex()> Integer.mod(5, 2) 1 iex()> String.trim(" Hello Elixir ") "Hello Elixir"

En Python / Java / Golang, debe import MODULE antes de poder usar funciones en ese MÓDULO, por ejemplo, Python

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

Entonces, lo que import en Elixir puede sorprenderte:

Usamos importar cuando queremos acceder fácilmente a funciones o macros desde otros módulos sin usar el nombre completo

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

Entonces, si desea escribir sqrt lugar de Integer.sqrt , trim lugar de String.trim , import le ayudará

iex()> import Integer Integer iex()> sqrt(100) 10.0 iex()> import String String iex()> trim(" Hello Elixir ") "Hello Elixir"

Esto puede causar problemas para leer el código y cuando hay un conflicto de nombres, por lo que no se recomienda en Erlang (el idioma que influye en Elixir). Pero no existe tal convención en Elixir, puede usarla bajo su propio riesgo.

En Python, el mismo efecto se puede hacer al:

from math import *

y solo se recomienda usar en algunos escenarios especiales / modo interactivo, para una escritura más corta / más rápida.

usar y requerir

Lo que hace que use / require diferente es que se relacionan con "macro", el concepto que no existe en Python / Java / Golang ... family.

No necesita import un módulo para usar sus funciones, pero necesita un módulo para usar sus 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

Aunque is_even puede escribirse como una función normal, es una macro porque:

En Elixir, Integer.is_odd / 1 se define como una macro para que pueda usarse como guardia.

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

use , para extraer de Elixir doc:

use requiere el módulo dado y luego llama a la devolución __using__/1 llamada __using__/1 , permitiendo que el módulo inyecte algún código en el contexto actual.

defmodule Example do use Feature, option: :value end

se compila en

defmodule Example do require Feature Feature.__using__(option: :value) end

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

Entonces escribir use X es lo mismo que escribir

require X X.__using__()

use/2 es una macro , la macro transformará el código en otro código para usted.

Deberá use MODULE cuando:

  • desea acceder a sus macros ( require )
  • Y ejecute MODULE.__using__()

Probado en Elixir 1.5


Consulte la página elixir-lang.org/getting-started/alias-require-and-import.html de la guía de inicio oficial de 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

Exigir

Elixir proporciona macros como mecanismo para la metaprogramación (escribir código que genera código).

Las macros son fragmentos de código que se ejecutan y expanden en el momento de la compilación. Esto significa que, para usar una macro, debemos garantizar que su módulo y su implementación estén disponibles durante la compilación. Esto se hace con la directiva require .

En general, no se necesita un módulo antes del uso, excepto si queremos usar las macros disponibles en ese módulo.

Importar

Usamos import siempre que deseamos acceder fácilmente a funciones o macros desde otros módulos sin usar el nombre completo. Por ejemplo, si queremos usar la función duplicate/2 del módulo List varias veces, podemos importarla:

iex> import List, only: [duplicate: 2] List iex> duplicate :ok, 3 [:ok, :ok, :ok]

En este caso, estamos importando solo la función duplicate (con arity 2) de List .

Tenga en cuenta que la import de un módulo lo require automáticamente.

Utilizar

Aunque no es una directiva, el use es una macro estrechamente relacionada con require que le permite usar un módulo en el contexto actual. Los desarrolladores use frecuencia la macro de use para incorporar la funcionalidad externa al ámbito léxico actual, a menudo módulos.

Detrás de escena, el use requiere el módulo dado y luego llama a la devolución __using__/1 llamada __using__/1 , lo que permite que el módulo inyecte algo de código en el contexto actual. En general, el siguiente módulo:

defmodule Example do use Feature, option: :value end

se compila en

defmodule Example do require Feature Feature.__using__(option: :value) end


use está destinado a inyectar código en el módulo actual, mientras que la import se usa para, bueno, importar funciones para su uso. Puede crear una implementación de use que importe automáticamente funciones, por ejemplo, como hago con Timex cuando agrega el use Timex a un módulo, eche un vistazo a timex.ex si desea saber a qué me refiero , es un ejemplo muy simple de cómo para construir un módulo que se pueda use ''d


import Module trae todas las funciones y macros del Module sin espacio de nombres en su módulo.

require Module permite usar macros de Module pero no las importa. (Las funciones del Module siempre están disponibles en espacios de nombres).

use Module primero requires módulo y luego llama a la macro __using__ en el Module .

Considera lo siguiente:

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

Esto no se compilará ya que ModA.moda() no se ha importado a ModB .

Sin embargo, se compilará lo siguiente:

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

Como cuando use d ModA , generó una declaración de import que se insertó en ModB .


use Module requiere Module y también invoca __using__ en él.

import Module trae la funcionalidad del Module al contexto actual , no solo lo requiere.