我预计它会被记录在 中Module,可能会引用structs,但没有什么乐趣。看到它与单个或一组参数一起使用。到目前为止我能找到的所有变体:
模块名称列表,例如
@derive [MyProtocol, Another]
模块名称 如
@derive Inspect
元组的形式
@derive {Protocol, key1: :val1, key2: val2}
元组列表,例如
@derive [{Prot1, :options}, {Prot2, key: :val}]
我发现唯一提到的地方@derive:
Kernel.defstruct/1宏文档中的“导出”部分InspectProtocol.derive/3宏的文档(在#7019中添加)不确定我是否只是忽略了一些东西,因此没有提出问题或拉取请求。
文档在defstruct那里:
对于列表中的每个协议
@derive,Elixir 将断言任何协议都有一个实现(无论回退到任何协议是否为真),并检查任何实现是否定义了回调__deriving__/3(通过Protocol.derive/3)。
和Protocol.derive/3:
如果您的实现传递了选项,或者如果您要基于结构生成自定义代码,则还需要实现一个定义为
__deriving__(module, struct, options)获取传递的选项的宏。
换句话说,@derive:
{protocol, options}其中是protocol将调用的协议__deriving__/3,并将作为第三个参数传递optionstermprotocol(其中protocol定义如上 - 描述协议模块的原子)与{protocol, []}因此,您的示例都可以重写为“更具描述性”,如下所示:
模块名称列表
@derive [MyProtocol, Another]
Run Code Online (Sandbox Code Playgroud)
是相同的
@derive [{MyProtocol, []}, {Another, []}]
Run Code Online (Sandbox Code Playgroud)模块名称
@derive Inspect
Run Code Online (Sandbox Code Playgroud)
是相同的
@derive [Inspect]
Run Code Online (Sandbox Code Playgroud)
哪个是相同的
@derive [{Inspect, []}]
Run Code Online (Sandbox Code Playgroud)元组
@derive {Protocol, key1: :val1, key2: val2}
Run Code Online (Sandbox Code Playgroud)
是相同的
@derive [{Protocol, [key1: :val1, key2: val2]}]
Run Code Online (Sandbox Code Playgroud)元组列表是“规范”形式
我希望这能澄清一切。