Elixir 为什么是长生不老药';什么是访问行为而不是协议?

Elixir 为什么是长生不老药';什么是访问行为而不是协议?,elixir,Elixir,在Elixir的最新版本中,访问不再作为协议实现,而是作为一种行为实现。据我所知,这种变化是由开发模式中的性能考虑因素引起的 现在,看看实现,我想知道这在内部是如何工作的,为什么选择这个实现。正如我们所看到的,Access通过底层映射的“\uuuuu struct\uuuuuu”键分派到结构的模块。AFAICS,这与OOP风格的多态性大致相同。关于这一点,有几个问题: 为什么这样更快 与协议相比,有哪些缺点?据我所知,它的可扩展性较差。还有其他的吗 到目前为止,我只在GenServer这样的环境

在Elixir的最新版本中,访问不再作为协议实现,而是作为一种行为实现。据我所知,这种变化是由开发模式中的性能考虑因素引起的

现在,看看实现,我想知道这在内部是如何工作的,为什么选择这个实现。正如我们所看到的,Access通过底层映射的“\uuuuu struct\uuuuuu”键分派到结构的模块。AFAICS,这与OOP风格的多态性大致相同。关于这一点,有几个问题:

  • 为什么这样更快
  • 与协议相比,有哪些缺点?据我所知,它的可扩展性较差。还有其他的吗
  • 到目前为止,我只在GenServer这样的环境中看到了一些行为,在GenServer中,回调模块在初始化时被捕获并保存在一个进程中(至少我假设是这样)。这里,访问行为从数据中获取回调模块。甚至可以为非结构的东西实现这种行为吗
  • 当人们对协议带来的额外好处不感兴趣时,这种分派是Erlang或Elixir中常见的最佳实践吗

  • 正如您已经提到的,
    Access
    的实现被更改为使用行为而不是协议。理由是性能

    • 协议是基于类型/数据的多态性,并且是Elixir独有的。这意味着它允许您根据数据结构进行调度
    • 行为是一种无类型的机制,它不依赖于数据结构,而是将模块作为参数。它们也被直接嵌入到系统中,性能更高

    虽然协议在基于数据类型进行调度时会为您带来很多麻烦,但由于它们的实现方式(整合),它们仍将用于
    访问

    因此,尽管在需要将某些功能绑定到数据结构而不是模块时,应该始终使用协议,
    Access
    是一种特殊情况

    由于
    Access
    协议在开发和测试模式下依赖于代码服务器(当未应用协议整合时),我们听到多个报告称,由于代码服务器成为具有多个进程的瓶颈,系统的性能受到很大影响

    发生这种情况的原因是
    Access
    协议最终被调用了数千次,我们对此没有多少改进(与大多数列表案例都是内联的可枚举协议相比)

    ~


    进一步阅读:

    • Github:
    • 长生不老药论坛:
    • 堆栈溢出:
    • 邮寄名单:
    • 博文:

    所以,这里没有答案,但有一个Elixir core邮件列表(在谷歌群组上)可能有助于回答您的问题。浏览一下主题,看起来这可能不是正确的列表。那里的人都在讨论核心语言提案,而我的问题更多的是关于风格的初学者问题。我真的不想在名单上乱发这个。不过原则上是个好主意。我可能会把这篇文章发布到另一个与长生不老药相关的列表中。如果你想知道设计中的决策,那么你需要长生不老药核心邮件列表。我的意思是,如果在任何时候讨论使用从协议到行为的访问更改背后的原因,以及该更改的其他属性——它将在邮件列表上。@MigratoryMonkeyMaster您看到相关的Github问题了吗?何塞很好地解释了原因:@PatrickOscity,谢谢你指出这一点。这确实是一本有趣的书。但是AFAICS的讨论主要是关于更改的原因,并且没有解释为什么选择这个具体的实现,所以它没有真正解决我问题的核心。