使用Malli声明式:merge与递归:ref时遇invalid-ref/invalid-schema错误
解决Malli中
:merge与相互递归:ref的兼容问题 问题原因
在Malli的:merge结构中使用相互递归的:ref时,Schema解析器在初始化注册表阶段,无法正确识别尚未完成解析的交叉引用,从而抛出invalid-ref或invalid-schema错误。
解决方案
在递归引用的外层包裹:lazy修饰符,延迟引用的解析时机,让Malli在实际验证时再解析相互依赖的Schema。修改后的代码如下:
(def ping-pong-registry {::ping [:maybe [:merge [:map [:value [:= "ping"]] [:person string?]] [:map [:child [:lazy [:ref ::pong]]]]]] ::pong [:maybe [:merge [:map [:value [:= "pong"]] [:bot string?]] [:map [:child [:lazy [:ref ::ping]]]]]]}) (def ping-pong-schema (m/schema [:schema {:registry ping-pong-registry} ::ping])) (m/validate ping-pong-schema {:value "ping" :person "Jane" :child {:value "pong" :bot "c-3po" :child {:value "ping" :person "Jane" :child {:value "pong" :bot "c-3po" :child {:value "ping" :person "Jane" :child nil}}}}})
原理说明
:lazy修饰符会告诉Malli不要在Schema初始化阶段立即解析内部的:ref,而是等到实际执行验证操作时才去解析引用的Schema。这就避免了相互递归结构在初始化时出现的“未定义引用”问题,同时保留了:merge声明式合并的需求。
内容的提问来源于stack exchange,提问作者sergelerner
相关产品推荐
相关产品推荐

