如何用宏实现仅匹配结构体名称的Elixir类型过滤函数?
解决Elixir宏批量生成结构体类型匹配函数的问题
问题根源
你当前的宏实现错误地使用Macro.escape/1处理了结构体实例(如%A{}),这会将结构体的所有默认字段(比如id: nil、foo: nil)都嵌入到模式匹配中,导致函数只能匹配字段全为默认值的结构体,而不是任意该类型的结构体。
正确实现
直接遍历结构体对应的模块(而非结构体实例),生成仅匹配结构体类型的模式:
defmodule Algo do alias Algo.{A, B} for mod <- [A, B] do def filter_by_type(collection, %unquote(mod){}) do for %unquote(mod){} = el <- collection, do: el end end end
原理说明
%unquote(mod){}会被展开为%A{}或%B{},和你手写的原函数模式完全一致,仅匹配对应类型的结构体,不检查字段值。- 遍历模块列表比遍历结构体实例更直接,避免了
Macro.escape/1带来的多余字段匹配问题。
验证
运行原测试用例,该实现会和手写的函数行为完全一致,成功过滤出对应类型的结构体。
内容的提问来源于stack exchange,提问作者user1453428
相关产品推荐
相关产品推荐

