엘릭서 : 사용 vs 가져 오기


134

차이 무엇 useimport?

주어진 컨텍스트를 현재 컨텍스트에 사용하기위한 간단한 메커니즘

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

다른 모듈에서 함수 및 매크로를 가져옵니다.

한 가지 차이점은 import특정 기능 / 매크로를 선택하고 use모든 것을 가져 오는 것입니다.

다른 차이점이 있습니까? 언제 다른 것을 사용 하시겠습니까?


빠른 요약 : import Module모듈 내에서 사용할 기능을 제공합니다. use Module사용할 함수를 가져오고 모듈에 공개합니다.
Jered

답변:


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

당신이 used와 같이 삽입 ModAimport문장을 생성 했다 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올바른 예제에서 import를 사용하는 것이 합리적 입니까?
Ryan-Neal Mes

35

use는 현재 모듈에 코드를 주입하기위한 것이며 import함수를 가져 오는 데 사용됩니다. use예를 들어 use Timex모듈에 추가 할 때 Timex와 마찬가지로 함수를 자동으로 가져 오는 구현을 구축 할 수 있습니다. 내가 무엇을 의미하는지 알고 싶다면 timex.ex를 살펴보십시오 . use'd 일 수있는 모듈


1
use보다 일반적 이라고 말하는 것이 정확 import합니까? 즉,의 기능 import은 다음의 일부입니다.use
User314159

1
import나는 당신이 구현할 수있는 말을 정확 알고하지 않는 한, 여전히 필요 importuse혼자하지만, 가능하다면 나는 놀라지 않을 것이다. use그래도 절대적으로 더 강력합니다. 예를 들어, 프로젝트 use에서 매우 복잡한 작업을 수행 exprotobuf하여 제한에 도달했는지 확인할 수 있습니다. 코드를 사용하여 모듈을 확장하고, 컴파일 타임에 코드를 실행하고, 모듈에 함수를 추가하는 등의 작업을 수행 할 수 있습니다. 기본적으로 import매크로의 기능과 결합 합니다.
bitwalker

자세한 설명과 코드 참조에 감사드립니다. 나는 지금 그것을 얻는다 생각한다. 저는 여전히 Elixir를 처음 사용하지만 더 많은 유스 케이스를 살펴보면 차이점이 분명하다고 생각합니다.
314159

문제 없습니다. 또 다른 훌륭한 곳은 Phoenix 웹 프레임 워크입니다. Chris McCord는 Elixir 매크로에 관한 책을 저술했으며 Phoenix에서 (을 포함하여 use) 많이 사용합니다 . 초보자보다 읽기가 훨씬 쉽습니다 exprotobuf.하지만 use한계에 도달 exprotobuf할 수 있으므로 얼마나 멀리 갈 수 있는지 보는 것이 유용 할 수 있습니다.
bitwalker

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 으로이야.

사용하다

지시어 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

Python / Java / Golang 언어의 배경으로 importvs 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엘릭서에서 당신을 놀라게 할 것입니다 :

정규화 된 이름을 사용하지 않고 다른 모듈에서 함수 또는 매크로에 쉽게 액세스 할 때마다 가져 오기를 사용합니다.

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에 영향을주는 언어 ) 에서는 권장되지 않습니다 . 그러나 Elixir에는 그러한 규칙이 없으므로 자신의 위험에 따라 사용할 수 있습니다.

파이썬에서도 다음과 같은 효과가 있습니다.

from math import * 

짧고 빠른 타이핑을 위해 일부 특수 시나리오 / 대화식 모드 에서만 사용하는 것이 좋습니다 .

사용 및 요구

무엇을 만드는가 use/require 개념 파이썬 / 자바 / 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 문서에서 발췌 :

사용하려면 주어진 모듈이 필요하고 그 모듈에서 __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에서 테스트


3

use Module 요구 Module 하고 또한 호출 __using__합니다.

import ModuleModule기능 뿐만 아니라 현재 컨텍스트에 기능을 제공 합니다.


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.

그건 그렇고, Elixir에는 더 많은 종속성 처리 명령이 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.