构造函数从包中导出,再次调用失败

以前写了一个包,想完善下,于是想把参数塞到一个struct里面去。

module DoubleRFs

export ParDBRF

struct ParDBRF # params of double rf
    # ===== 这些参数需要提前准备 =====
    v1::Float64
    r::Float64
    ϕs::Float64
    ϕ2s::Float64
    h1::Int64
    h::Int64
    circum::Float64
    centerenergy::Float64
    αc::Float64
    ξ::Float64
    νy::Float64
    σδ::Float64
    # ===== 下面的参数会自动计算 ======
    ωβ::Float64
    ω0::Float64
    ωξ::Float64
    γ::Float64
    η::Float64
    # 内部构造方法
    Param(v1, r, ϕs, ϕ2s, h1, h, circum, centerenergy, αc, ξ, νy, σδ)=new(v1, r, ϕs, ϕ2s, h1, h, circum, centerenergy, αc, ξ, νy, σδ, νy*2*π*299792458.0/circum, 2*π*299792458.0/circum, νy*2*π*299792458.0/circum*ξ/(αc-1/(centerenergy/0.511e6)^2), centerenergy/0.511e6, αc-1/(centerenergy/0.511e6)^2)
end
Base.broadcastable(x::ParDBRF) = Ref(x)

end

这个结构体没有塞进模组,在Jupyter Notebook中,是能够运行的。
但是我当我打包成一个包,再调用这个包时,就出现了:

> param=DoubleRFs.ParDBRF(3639505.370587, 0.1833, 2.0399026, 5.708, 756, 3, 1360.4, 6e9, 0.0000156073, 0.0, 106.27, 1.06e-3)
MethodError: no method matching DoubleRFs.ParDBRF(::Float64, ::Float64, ::Float64, ::Float64, ::Int64, ::Int64, ::Float64, ::Float64, ::Float64, ::Float64, ::Float64, ::Float64)

Stacktrace:
 [1] top-level scope
   @ In[3]:1
 [2] eval
   @ .\boot.jl:360 [inlined]
 [3] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
   @ Base .\loading.jl:1116

只能用外部构造函数方法。

内部函数名称写错了,改写后可用。

param=DoubleRFs.ParDBRF(3639505.370587, 0.1833, 2.0399026, 5.708, 756, 3, 1360.4, 6e9, 0.0000156073, 0.0, 106.27, 1.06e-3)

嗯嗯,谢谢,我搬到包里时觉得Param这个名字太抽象,改了名,但是没改全。

不过亲测内部构造函数,导出也不能用。还得是外部构造函数。 Struct in my package cannot be called correctly - New to Julia - Julia Programming Language (julialang.org)

@XuJingye 内部的同名派发是可以正常用的,你不妨重新试试这个例子(纯粹是变量名写错了)。引用链接里也回答了 “You have defined a function as an inner constructor, removing the default constructors.” 建议用外部函数是因为会覆盖原始派发,实际上,如果你想保留原始派发,在内部一并写上就够了。


结构体默认会定义内部函数

struct Foo
    x1
    x2
    # Foo(x1, x2) = new(x1, x2) # 默认
end

但如果你主动改写了内部函数,比如

struct Foo
    x1
    x2
    Foo(x1) = new(x1, x1)
end

那默认函数 Foo(x1, x2) 会被 Foo(x1) 替换,再用 Foo(x1, x2) 就会报错。