@derive 模块属性的具体语法是什么?它在哪里明确记录?

tor*_*tte 7 elixir

我预计它会被记录在 中Module,可能会引用structs,但没有什么乐趣。看到它与单个或一组参数一起使用。到目前为止我能找到的所有变体:

我发现唯一提到的地方@derive:


不确定我是否只是忽略了一些东西,因此没有提出问题或拉取请求。

Hau*_*eth 5

文档在defstruct那里:

对于列表中的每个协议@derive,Elixir 将断言任何协议都有一个实现(无论回退到任何协议是否为真),并检查任何实现是否定义了回调__deriving__/3(通过Protocol.derive/3)。

和Protocol.derive/3:

如果您的实现传递了选项,或者如果您要基于结构生成自定义代码,则还需要实现一个定义为__deriving__(module, struct, options)获取传递的选项的宏。

换句话说,@derive:

  • 接受以下形式的元组列表,{protocol, options}其中是protocol将调用的协议__deriving__/3,并将作为第三个参数传递optionsterm
  • protocol(其中protocol定义如上 - 描述协议模块的原子)与{protocol, []}
  • 如果是单个派生模块,您可以省略将所有内容包装在列表中并直接使用定义

因此,您的示例都可以重写为“更具描述性”,如下所示:

  1. 模块名称列表

    @derive [MyProtocol, Another]
    
    Run Code Online (Sandbox Code Playgroud)

    是相同的

    @derive [{MyProtocol, []}, {Another, []}]
    
    Run Code Online (Sandbox Code Playgroud)
  2. 模块名称

    @derive Inspect
    
    Run Code Online (Sandbox Code Playgroud)

    是相同的

    @derive [Inspect]
    
    Run Code Online (Sandbox Code Playgroud)

    哪个是相同的

    @derive [{Inspect, []}]
    
    Run Code Online (Sandbox Code Playgroud)
  3. 元组

    @derive {Protocol, key1: :val1, key2: val2}
    
    Run Code Online (Sandbox Code Playgroud)

    是相同的

    @derive [{Protocol, [key1: :val1, key2: val2]}]
    
    Run Code Online (Sandbox Code Playgroud)
  4. 元组列表是“规范”形式

我希望这能澄清一切。