内容简介:Elixir 的元编程能力,拥有和 Lisp 一样的代码即数据的特点。它的方法名,参数和方法体等,能用 List 的数据格式包装起来,传给宏(Macro),再做分析或者扩展。且看所以,通过宏(Macro),我们可以动态生成代码,实现 AOP 在方法前后包装自己的逻辑等。比如下面的代码,
Elixir 的元编程能力,拥有和 Lisp 一样的代码即数据的特点。它的方法名,参数和方法体等,能用 List 的数据格式包装起来,传给宏(Macro),再做分析或者扩展。且看 Programming Elixir ≥ 1.6 书中很简单的展示代码。
defmodule My do defmacro macro(param) do IO.inspect param end end defmodule Test do require My My.macro do 1 + 2 else 3 + 4 end end # => [ do: {:+, [line: 7], [1, 2]}, else: {:+, [line: 9], [3, 4]} ]
IO.inspect
(类似于 System.out
或者 console.log
) 打印出来的就是宏接收到的以 List 格式包装的代码。
所以,通过宏(Macro),我们可以动态生成代码,实现 AOP 在方法前后包装自己的逻辑等。比如下面的代码, times_3
和 times_4
就是动态生成的方法。
defmodule Times do defmacro times_n(n) do quote do def unquote(:"times_#{n}")(v) do unquote(n) * v end end end end defmodule Test do require Times Times.times_n(3) Times.times_n(4) end IO.puts Test.times_3(4) #=> 12 IO.puts Test.times_4(5) #=> 20
Protocol
“多态”,对于学过面向对象的开发人员来说,应该是一个很熟悉的概念了。单一的接口,不同的类型或实现。
在 JAVA 里,如果你想实现“多态”,你必须修改那些类的源代码,让它们都继承某个公共类,或者实现某个统一的接口。假如,你想为第三方的一些“多态”类添加一些行为,但你没办法修改它的源代码,这就比较尴尬了。然后各种幺蛾子的方法都会弄出来。
但是,Elixir Protocol 的实现方式,可以让你不必修改对方的源代码的情况下,实现扩展。借 Programming Elixir ≥ 1.6 书中的例子来说明一下。
defprotocol Collection do @fallback_to_any true def is_collection?(value) end defimpl Collection, for: [List, Tuple, BitString, Map] do def is_collection?(_), do: true end defimpl Collection, for: Any do def is_collection?(_), do: false end Enum.each [1, 1.0, [1, 2], {1, 2}, %{}, "cat"], fn value -> IO.puts "#{inspect value}:#{Collection.is_collection?(value)}" end # 打印出来的结果就是: 1: false 1.0: false [1, 2]: true {1, 2}: true %{}: true "cat": true
上面就为系统内置的数据类型,定义了一个很简单的 “多态” 函数,检测哪些是属于集合类。嗯,就是这么简洁。
Elixir 除了功能强大,学习它还可以给自己一种非常不同的思维方式。如果说 Elixir 有什么不好,那就是周边的人少了点吧,Slack Channel 才 2W 多人,遇到问题找答案可就不是那么容易的事情了。不过,我觉得还是值得的。
最后附上 Joe Armstrong 老爷子,Erlang 作者对 Elixir 的第一印象文章 A week with Elixir 。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Istiod——回到单体的理由
- 使用消息队列的 10 个理由
- 10个学习Python的理由
- [译] Istiod:回到单体的理由
- 使用 TypeScript 的 10 个 理由
- 一千个不用 Null 的理由
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。