Julia 具体类型的子类型
为了练习Julia,我使用迭代器接口实现了一个包含一些固定步长ODE解算器(Euler、Runge Kutta、Bulirsch Stoer)的小模块 我的想法是使用多重分派将函数Julia 具体类型的子类型,julia,Julia,为了练习Julia,我使用迭代器接口实现了一个包含一些固定步长ODE解算器(Euler、Runge Kutta、Bulirsch Stoer)的小模块 我的想法是使用多重分派将函数next的正确方法应用于特定的迭代器,但是Euler和Runge-Kutta迭代器类型(实际上是不可变的)使用相同的数据 因此,我必须在以下两者之间做出选择: 创建两个不可变的类型,除了名称或 将一个唯一的不可变的与一个附加字段(比如解决方法)打包,并使用分支而不是多次分派来解决此问题 这两个选择对我来说都很笨拙(尤其
next
的正确方法应用于特定的迭代器,但是Euler和Runge-Kutta迭代器类型(实际上是不可变的
)使用相同的数据
因此,我必须在以下两者之间做出选择:
不可变的
与一个附加字段(比如解决方法
)打包,并使用分支而不是多次分派来解决此问题solving\u method
字段)
在阅读关于Julia继承的在线讨论时,我了解到Julia没有(也永远不会有)具体类型的子类型,这意味着不能以这种方式向父类型“添加字段”
但是为什么我不能将具体类型的子类型仅仅用于分派目的呢?也许可以尝试参数化类型
abstract OdeType
abstract Euler <: OdeType
abstract RK4 <: OdeType
immutable Common{T<:OdeType}
x::Int
end
抽象类型
抽象Euler解决这类问题的一种惯用方法是创建一个存储参数或解算器状态的类型,然后使用第二个不可变项来指定方法:
type SolverOptions
# ... step size, error tol, etc.
end
immutable RungeKutta end
immutable Euler end
function solve(problem::ODE, method::RungeKutta, options::SolverOptions)
# ... code here ...
end
function solve(problem::ODE, method::Euler, options::SolverOptions)
# ... code here ...
end
当然,如果您想在其中存储一些数据,RungeKutta和Euler不需要为空。这并不总是最好的解决方案(我不能确定它是否适用于您的特定情况),但当您试图防止字段名重复时,它会有所帮助