我有一个类似的结构
@kwdef mutable struct Params{B, C}
a::Float64 = 42
end
其中
B
和 C
是符号,用于确定在针对不同符号组合重载的许多函数中使用哪个函数。有效符号例如 :constant
和 :exponential
。我想编写一个函数,如果其中一个符号与参数化结构中的相应符号匹配,则该函数将被调用,并且无论其他符号如何,也应该调用该函数。举个例子,
p = Params{:constant, :gaussian}()
foo(p::Params{:constant, <:Symbol}) = 42
foo(p) # should return 42, but throws an error
我该怎么做?
背景
的图 3)。使用简化模型,请参阅以下代码作为我想要执行的操作的示例:
using UnPack
using DynamicalSystems
using Distributions
@kwdef mutable struct Params{B, C}
mu_p = 10e-6
sigma_p = 9
mu_b = 2
sigma_b = 100
mu_r = 0.1
sigma_r = 2.6
bcr_0 = 0.05
cd_0 = 0.025
end
function germinal_center_regulation_rule(u, params, t)
@unpack mu_p, sigma_p, mu_b, sigma_b, mu_r, sigma_r,
@unpack bcr0, cd0 = params
p, b, r = u
#######IMPORTANT PART############
bcr = compute_bcr(;u, params, t)
cd40 = compute_cd40(;u, params, t)
#################################
pdot = mu_p + sigma_p/b
bdot = mu_p + sigma_p/b - bcr*b
rdot = mu_r * sigma_r/r
return SVector(pdot, bdot, rdot)
# Different methods for different parameterized struct
compute_bcr(;u, params::Params{:constant, <:Symbol}, t) = 15
compute_bcr(;u, params::Params{:gaussian, <:Symbol}, t) = pdf(Normal(), t)
compute_cd40(;u, params::Params{<:Symbol, :reciprocal}, t) = params[:bcr0]/u[2]
compute_cd40(;u, params::Params{<:Symbol, :gaussian}, t) = pdf(Normal(), t)
# Example usage
p_constant_bcr_gaussian_cd40 = Params{:constant, :gaussian}()
u0 = [0.2, 5.0, 0.2]
mixed_ds = CoupledODEs(
germinal_center_regulation_rule, u0, p_constant_bcr_gaussian_cd40)
total_time = 200
X, t = trajectory(ds, total_time)
p_gaussian_bcr_gaussian_cd40 = Params{:gaussian, :gaussian}()
gaussian_ds = CoupledODEs(
germinal_center_regulation_rule, u0, p_gaussian_bcr_gaussian_cd40)
total_time = 200
X, t = trajectory(ds, total_time)
T<:U
表明
T
是 U
的子类型。但就你而言, :gaussian
不是 Symbol
的 subtype,而是 is
Symbol
。你可以用解决这个问题
foo(p::Params{:constant, S}) where {S} = 42
如果必须确保
S
是
Symbol
,最好在 Params
的构造函数中执行此操作。julia> @kwdef mutable struct Params{B, C}
a::Float64 = 42
function Params{B, C}(a) where {B, C}
if !(B isa Symbol && C isa Symbol)
error("Params generics must be Symbols")
end
return new{B, C}(a)
end
end
julia> Params{:a, :b}(2)
Params{:a, :b}(2.0)
julia> Params{:a, 1}(2)
ERROR: Params generics must be Symbols
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:35
[2] Params{:a, 1}(a::Int64)
@ Main ./REPL[49]:5
[3] top-level scope
@ REPL[51]:1