繁体   English   中英

直接在Elixir中使用调用模块函数defdelegate和def之间有什么区别

[英]What is the difference between defdelegate and def with call module function directly in Elixir

我有一个主要用作命名空间的模块。 我们称之为Bla 还有其他子模块,它们具有对该子模块具有特定功能的方法。

但是,我想有两个选择:

1)导入主模块Bla并直接使用子模块中的所有函数(不单独写入多个导入)

2)仅导入像Bla.Subbla这样的特定子模块,仅使用此模块中的函数而不从其他子模块导入函数

这就是我所拥有的:

defmodule Bla do
  defdelegate bla_func(text), to: Bla.Subbla
  defdelegate bla_func(text, opts), to: Bla.Subbla
end

defmodule Bla do
  def bla_func(text), do: Bla.Subbla.bla_func(text)
  def bla_func(text, opts), do: Bla.Subbla.bla_func(text, opts)
end

这样做的正确方法是什么? 我有两个选择,但不知道,也许,还有更好的选择。 这两个选项是否相同? 哪个更好? 性能有什么不同吗?

我能想到的一些差异:

  1. 当您使用defdelegate您的意图非常明确,您只是将该方法委托给另一个模块中的另一个方法。 而这只是一个愚蠢的货运代理人。
  2. 使用defdelegate您无法更改arguments ,无论是顺序,添加还是删除参数。 所以,如果你真正想要的是转发方法调用使用defdelgate因为没有更少的空间搞砸了。
  3. 在某些情况下, defdelegate不是一个选项,因为您需要向转发功能添加更多数据,在这种情况下您实际上没有选项。

因此,底线是:如果可能的话总是使用defdelegate ,你将避免使用它的一些类错误。 例如下面:

defmodule Greet do
  def greet(name, greeting) do
    IO.puts "#{greeting} #{name}"
  end
end

defmodule DelegatedGreet do
  defdelegate greet(name, greeting), to: Greet
end

defmodule BuggyGreet do
  # scope for bugs like these
  def greet(name, greeting), do: Greet.greet(greeting, name)
end

正如@JustMichael所说,在这种情况下use是很好的。 它完全符合我的需要。

defmodule SomeModuleWhereINeedSubbla do
  use Bla

  useful_func   # => Will print "Bla.Subbla.useful_func"
end

defmodule Bla do
  defmacro __using__(_) do
    quote do
      import Bla.Subbla
    end
  end
end

defmobule Bla.Subbla do
  def useful_func(), do: IO.puts "Bla.Subbla.useful_func"
end

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM