在Julia中,是否可能有两个同名的结构,但被分配了不同的类型,从而可以区分?
我一直在读https://docs.julialang.org/en/v1/manual/types/#Parametric-Types-1,它似乎正朝着我想要的方向发展,但我无法让它工作.
在分子模拟力场中,存在描述分子扭转角的二面体参数.有不同的种类,例如,目的,让他们限制为2种:适当和不适当。我希望有两种结构,它们都叫做二面体,但给出了“适当”和“不适当”的类型。然后,我将有特定于每一种类型的方法来计算由二面体引起的力。我认为抽象的参数类型能让我最接近我想要的东西,但我不能把它们分类.
abstract type proper end
abstract type improper end
struct Dihedral <: proper
ai::Int64
kparam::Vector{Float64}
end
struct Dihedral <: improper
ai:Int64
kparam::Float64
end
上面的代码不工作..。我试过用
abstract type dihedral end
abstract type proper <: dihedral end
abstract type improper <: dihedral end
struct Dihedral <: dihedral{proper}
...
end
struct Dihedral <: dihedral{improper}
...
end
但是我总是因为重新定义Dihedral
而惹上麻烦
ERROR: LoadError: invalid redefinition of constant Dihedral
Stacktrace:
[1] top-level scope at none:0
我的想法是,我可以添加更多类型的二面体,我需要做的就是加入他们的方法和模拟将自动使用新的dihedral.methods。如果我尝试用不同的名称构造结构,那么我就必须使用If语句将程序引导到正确的结构,然后使用正确的方法.这就是我想要避免的,
if dihedraltype == "proper"
struct_proper(...)
elseif dihedraltype =="improper"
struct_improper()
elseif dihedraltype == "newStyle"
struct_newStyle()
end
使用此方法,我必须在代码中找到调用二面体并添加新类型的所有位置.二面体只是一个例子,有许多“现象”,有不同的方法来计算这些现象。
发布于 2019-01-26 21:03:47
如果要使用参数类型,我将使用以下方法:
abstract type DihedralType end
struct Proper <: DihedralType
ai::Int64
kparam::Vector{Float64}
end
struct Improper <: DihedralType
ai::Int64
kparam::Float64
end
struct Dihedral{T<:DihedralType}
value::T
end
Dihedral(ai::Int64, kparam::Vector{Float64}) = Dihedral(Proper(ai, kparam))
Dihedral(ai::Int64, kparam::Float64) = Dihedral(Improper(ai, kparam))
现在你可以写:
Dihedral(1, [1.0, 2.0])
Dihedral(1, 1.0)
Dihedral
类型的参数向您传递您正在处理的对象的类型。然后,有些方法可能是通用的,并调用Dihedral
,例如:
julia> ai(d::Dihedral) = d.value.ai
ai (generic function with 1 method)
julia> ai(Dihedral(1, 1.0))
1
julia> ai(Dihedral(1, [1.0, 2.0]))
1
julia> kparam(d::Dihedral) = d.value.kparam
kparam (generic function with 1 method)
julia> kparam(Dihedral(1, 1.0))
1.0
julia> kparam(Dihedral(1, [1.0, 2.0]))
2-element Array{Float64,1}:
1.0
2.0
有些可能是特定于类型参数的:
julia> len(d::Dihedral{Proper}) = length(kparam(d))
len (generic function with 1 method)
julia> len(Dihedral(1, [1.0, 2.0]))
2
julia> len(Dihedral(1, 1.0))
ERROR: MethodError: no method matching len(::Dihedral{Improper})
Closest candidates are:
len(::Dihedral{Proper}) at REPL[15]:1
Stacktrace:
[1] top-level scope at none:0
这种方法能给你带来你所期望的吗?
编辑
实际上,也许一种更简单的方法可能对您来说就足够了(取决于用例)。只需定义:
abstract type AbstractDihedral end
struct Proper <: AbstractDihedral
ai::Int64
kparam::Vector{Float64}
end
struct Improper <: AbstractDihedral
ai::Int64
kparam::Float64
end
然后根据DihedralType
实现方法,如果它们对于所有二面体都是通用的,并且如果您想向给定的具体类型中添加一些特定的方法,只需在签名中添加这个具体类型的方法。例如:
ai(d::AbstractDihedral) = d.ai
kparam(d::AbstractDihedral) = d.kparam
len(d::Proper) = length(d.kparam) # will not work for Improper
在这种方法中,您不需要使用参数类型。区别在于,在参数类型方法中,您可以提取出与“父”结构的所有二面体相同的参数,并在“包装”结构中只定义二面体特定的参数。在第二种方法中,每次为每个结构定义所有字段。
https://stackoverflow.com/questions/54382340
复制相似问题