[Erlang 0112] Elixir Protocols

Why Elixir

为什么要学习Elixir?答案很简单,为了更好的学习Erlang.这么无厘头的理由?

Erlang语法设计几乎没有考虑过取悦开发者,所以学习之初的门槛略高.对于已经克服了最初语法障碍的同学,Elixir其实没有什么吸引力. 在Elixir之前已经有很多类似的项目,比如http://lfe.github.io Elixir类似思路的还有http://reia-lang.org 在前,但Elixir显然做得更好一些.看这些语言的时候,会有一种感觉:把这语言语法层面做优化调整,理想状态就是Erlang的样子吧!

那为什么要投入时间到Elixir? 深入Elixir内部,可以看到很多非常棒的设计,这些设计并不陌生,之前散见于各种开源项目.不过现在Elixir将这些解决方案整合在一起,而且更具有系统性.对我来说,这是一个很好的切入点.对于很多Ruby开发者来讲,Elixir具有很强的语法亲和力,而这点对我来讲没有什么意义,其实我反倒觉得Elixir在语法层面复杂了很多,需要"记住"的规则比较多,而Erlang这方面要精简很多.

多态

维基百科上对多态的定义 polymorphism is the provision of a single interface to entities of different types. [Link]对不同类型的数据实体提供一致的处理接口,对于这个定义有很多实现方式,比如接口,泛型.在Elixir提到多态的时候,是这样描述的:

Elixir also provides first-class support for pattern matching, polymorphism via protocols (similar to Clojure‘s), aliases and associative data structures (usually known as dicts or hashes in other programming languages).

也就是说它使用了类似Clojure Protocol的机制实现多态,那我们先看看Clojure里面的Protocol是怎样的:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

(ns
elixir-demo )

(defprotocol 
Concatenatable

  (cat
[
this other]))

(extend-type
java.util.List

   Concatenatable

    (cat
[
this other]

      (concat
this other))
)

(extend-type
String

  Concatenatable

  (cat
[
this other]

    (.concat
this other))
)

(println

   (cat
[1,2,3,4] [5,6,7]))

(println

   (cat
"Hello
"
 "World!!!!" ))

  

输出结果:

(1 2 3 4 5 6 7)

Hello World!!!!

这个,我们在C#中可以找到形式上非常类似的东西,看一个例子:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

public static class TypeExtensions

    {

        public static void Dump(this int num)

        {

            Console.WriteLine(string.Format("The
int number is :{0} \r\n "
,
num));

        }

        public static void Dump(this double num)

        {

            Console.WriteLine(string.Format("The
float number is :{0} \r\n "
,
num));

        }

        public static void Dump<T>(this IEnumerable<T>
items)

        {

            StringBuilder
sb =
new StringBuilder("Data:");

            foreach (var item
in items)

            {

                sb.AppendFormat("{0}\n",
item);

            }

            Console.WriteLine(sb.ToString());

        }

    }

  

调用的代码:


1

2

3

4

5

6

7

8

static void Main(string[]
args)

       {

           12.Dump();

           (12.23).Dump();

           (new List<string>()
{
"123",
"ok",
"test" }).Dump<string>();

           Console.ReadLine();

       }

  

这个在C#中被称为Extension Methods ,可以点击这里查看详细讲解:http://msdn.microsoft.com/en-us/library/bb383977.aspx

Elixir Protocols

下面,看看Elixir的Protocol,下面选取的例子来自Elixir中的chars.ex https://github.com/elixir-lang/elixir/blob/master/lib/elixir/lib/string/chars.ex

这个模块为大部分(有些数据类型不支持)数据类型增加了一个to_string的方法,首先定义了一个protocol:


1

2

3

defprotocol
String.Chars
do

  def
to_string(thing)

end

定义了protocol之后,下面就要按照各种类型做首先,下面截取的代码是针对integer和float的处理:

 


1

2

3

4

5

6

7

8

9

10

11

defimpl
String.Chars,
for:
Integer do

  def to_string(thing)
do

    integer_to_binary(thing)

  end

end

defimpl
String.Chars,
for:
Float
do

  def to_string(thing)
do

    iolist_to_binary(:io_lib_format.fwrite_g(thing))

  end

end

 

调用的时候,对于没有实现的情况


1

2

3

4

5

6

7

8

9

10

11

12

iex(8)>
to_string([
1,2])

<<1,
2>>

iex(9)>
to_string(
:a

"a"

iex(10)>
to_string(
12.3)

"12.3"

iex(11)>
to_string(
12)

"12"

iex(12)>
to_string({
1,2})

**
(Protocol.UndefinedError) protocol
String.Chars
not implemented
for {1,
2}

    /data2/src_elixir/elixir/lib/elixir/lib/string/chars.ex:3:
String.Chars.impl_for!/1

    /data2/src_elixir/elixir/lib/elixir/lib/string/chars.ex:17:
String.Chars.to_string/1

可以限定的数据类型有:Record,Tuple,Atom,List,BitString,Integer,Float,Function,PID,Port,Reference,Any

Protocol的代码实现在https://github.com/elixir-lang/elixir/blob/master/lib/elixir/lib/protocol.ex 等我们完成了对Elixir宏的探索之后,再回来仔细看Protocol的实现.

{ok,"今天先到这里"}

最后小图一张,2013大事记:

  

时间: 2024-10-29 10:45:40

[Erlang 0112] Elixir Protocols的相关文章

简单Elixir游戏服务器-安装Elixir

用WebInstaller 安装半天也没下载成功文件. 改成直接下载erlang 和 elixir 预编译包了. 安装很简单,最后设置好环境变量. cmd 执行 elixir -v 最后顺便下载了个git hub windows 客户端,以前都是内网用git. 这回希望能写完这个简单系列,发布代码出去.

《Elixir in Action》书评及作者问答录(作者 Sergio De Simone ,译者 邵思华 发布于 2015年9月29日)

<Elixir in Action>是由Manning所出版的一本新书,本书为读者介绍了Elixir这门语言以及Erlang虚拟机,同时也讨论了与并发编程.容错以及与高可用性相关的话题.InfoQ有幸与本书的作者Sa?a Juri?进行了一次访谈. <Elixir in Action>的内容源自于Juri?在Erlang方面的经验,他为此特意创建了一个博客,为来自面向对象背景的程序员展现Erlang的优势.Juri?之后转而使用Elixir,这是一种函数式的并发编程语言,它的目标是

CNCF LandScape Summary

CNCF Cloud Native Interactive Landscape 1. App Definition and Development 1. Database Vitess:itess is a database clustering system for horizontal scaling of MySQL. Apache CarbonData:Apache CarbonData is an indexed columnar data format for fast analyt

ARM Cortex-M7的内存:太大还是不够?

毫无疑问,ARM Cortex-M7 - 拥有强大的内存和处理能力 –以即使在几年前都难以想象的方式扩展了微控制器的功能.该处理器被定位成为物联网(IOT)的核心构建模块的事实,更是夺人眼目. 本文引用地址:http://www.eepw.com.cn/article/264892.htm 事实上,意法半导体的STM32 F7系列在9月的ARM科技论坛上荣获了最佳表现奖.这是第一款采用ARM的Cortex-M7内核的32位MCU家族,拥有320KB SRAM和1024KB闪存.爱特梅尔采用Cor

Algebraic Data Type 及其在 Haskell 和 Scala 中的表现

http://songkun.me/2018/07/12/2018-07-12-adt-in-haskell-and-scala/ 函数式编程接触久了以后,我们会发现很多 FP 语言(这里指静态 FP 语言)具有不少类似的语言特性,这非常自然,因为语言特性就那么多,好用.实用的特性更少,这一方面造成了语言之间的同质化,另一方面也减轻了我们语言切换的成本,算是有利也有弊吧. 常见的静态函数式语言有 Haskell.Standard ML.OCaml.Scala 等,它们之间非常类似,共有的特性有:

[Erlang 0109] From Elixir to Erlang Code

Elixir代码最终编译成为erlang代码,这个过程是怎样的?本文通过一个小测试做下探索. 编译一旦完成,你就看到了真相 Elixir代码组织方式一方面和Erlang一样才用非常扁平的代码模块结构,另一方面Elixir同时支持嵌套.Elixir比较方便的一点是可以在Elixir Shell中完成对模块的定义.看下面的方式: iex> defmodule Math do ...> def sum(a, b) do ...> a + b ...> end ...> end ie

Erlang/Elixir精选Q&amp;A

精选的定位是什么? 已至2019年,Erlang/Elixir中文社区还是一座黑暗森林,每个技术人都怀揣着自己独有的葵花宝典独自摸索,没有一个开放的分享平台,大量优质文章没有得到该有的关注. 与此同时,现代人所面临的世界正在渐渐变窄,信息茧房让人在互联网上关注越来越趋同:永远追逐热点的流量则导致许多新媒体的文章质量非常糟糕. 技术每分每秒都在变化和进步,无数的热榜升降更替.人们对信息的需求,从来没有像今天这样旺盛过. 本精选记录三年后重读依然还是能有所收获的文章,创造一个能够把点连成线汇成面,升

Erlang/Elixir精选-第1期

第1期(20191202) 文章 A short guide to the structure and internals of the?Erlang distributed messaging facility. Erlang分布式启动流程源码阅读指南: 节点启动时通过epmd互相发现彼此. net_kernel启动tcp建立稳定的长连接流程,handshake,setnode,set_cookie. 节点间发消息使用的数据格式external term format. How to open

Erlang/Elixir精选-第2期(20191209)

Spot The Discrepancies with Dialyzer for Erlang. 如何在大型Erlang项目中从零开始一步步践行Dialyzer. Which companies are using Erlang, and why? 哪一些公司正在生产上使用Erlang?这是HackerNews上的头条新闻,在首次发布四个月后,访问量仍然很高. An Unprecedented Subtraction. 为什么[1, 2, 3] -- [1, 2] -- [3] = [3]. R