在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
Run Code Online (Sandbox Code Playgroud)
上面的代码不起作用......我尝试过使用
abstract type dihedral end
abstract type proper <: dihedral end
abstract type improper <: dihedral end
struct Dihedral <: dihedral{proper}
...
end
struct Dihedral <: dihedral{improper}
...
end
Run Code Online (Sandbox Code Playgroud)
但我总是因重新定义而陷入困境 Dihedral
ERROR: LoadError: invalid redefinition of constant Dihedral
Stacktrace:
[1] top-level scope at none:0
Run Code Online (Sandbox Code Playgroud)
我的想法是我可以添加更多类型的二面角,我需要做的就是添加他们的方法,模拟将自动使用新的dihedral.methods.如果我尝试使用不同名称的结构,那么我开始使用if语句将程序引导到正确的结构,然后使用正确的方法......这就是我想要避免的,即,
if dihedraltype == "proper"
struct_proper(...)
elseif dihedraltype =="improper"
struct_improper()
elseif dihedraltype == "newStyle"
struct_newStyle()
end
Run Code Online (Sandbox Code Playgroud)
使用这种方法我会找到我的代码,我调用二面角和添加新类型的所有地方......二面角仅仅是一个例子,还有很多"phenomenas"有计算的现象,不同的方法.
如果要使用参数类型,我会使用以下方法:
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))
Run Code Online (Sandbox Code Playgroud)
现在你可以写例如:
Dihedral(1, [1.0, 2.0])
Dihedral(1, 1.0)
Run Code Online (Sandbox Code Playgroud)
类型参数会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
Run Code Online (Sandbox Code Playgroud)
有些可能是特定于类型参数的:
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
Run Code Online (Sandbox Code Playgroud)
这种方法能否满足您的期望?
编辑
实际上,一个更简单的方法可能就足够了(取决于用例).只需定义:
abstract type AbstractDihedral end
struct Proper <: AbstractDihedral
ai::Int64
kparam::Vector{Float64}
end
struct Improper <: AbstractDihedral
ai::Int64
kparam::Float64
end
Run Code Online (Sandbox Code Playgroud)
然后根据DihedralType
它们对所有二面角是否通用来实现方法,如果要为给定的具体类型添加一些特定方法,只需在签名中添加此具体类型的方法即可.例如:
ai(d::AbstractDihedral) = d.ai
kparam(d::AbstractDihedral) = d.kparam
len(d::Proper) = length(d.kparam) # will not work for Improper
Run Code Online (Sandbox Code Playgroud)
在这种方法中,您不需要使用参数类型.不同之处在于,在参数类型方法中,您可以将所有二面角相同的参数提取到"父"结构,并在"包裹"结构中仅定义二面体特定参数.在第二种方法中,您每次都为每个结构定义所有字段.
归档时间: |
|
查看次数: |
283 次 |
最近记录: |