Julia导入函数缺失其他模块定义的方法如何解决
错误根因
你遇到的报错本质是Julia的函数命名空间规则问题:
- 模块A中定义的
f是属于A的独立泛型函数 - 模块B中是给
A.f扩展了针对Bb类型的方法,属于对同一个泛型函数的方法补充 - 模块C中没有显式导入
A.f就直接定义f(::Cc),相当于创建了属于C的新泛型函数C.f,和A.f完全无关 - 你在
g方法中调用的f(model.btype)只会查询C.f的方法表,自然找不到针对B.Bb类型的实现
解决方法
不需要在C中导入B,只要确保C中操作的f是来自A的同一个泛型函数即可,有两种常用写法:
写法1:显式指定调用A的泛型函数
module C using Main.A struct Cc btype :: A.Ab end # 扩展A.f的方法,而非定义新函数 A.f(model::Cc) = A.f(model.btype) function g(model::Cc) @show A.f(model) end export Cc, g end
写法2:提前导入A的f到当前作用域
module C using Main.A # 导入A的f到当前作用域,后续定义f方法都是对A.f的扩展 import Main.A: f struct Cc btype :: A.Ab end f(model::Cc) = f(model.btype) function g(model::Cc) @show f(model) end export Cc, g end
原理说明
Julia的多重派发是基于泛型函数的方法表实现的,只要所有实现都是对同一个泛型函数A.f的方法扩展,运行时会自动根据参数的实际类型匹配所有已注册的方法,不管方法是在哪个模块中定义的,完全不需要C模块提前感知B模块的存在,符合你要求的框架通用性。
修改后运行代码会正常输出:
f(model) = "B"
内容的提问来源于stack exchange,提问作者Tanj。
相关产品推荐
相关产品推荐

