获取 UndefVarError:尝试在 Julia 中定义具有内部构造函数的结构时未定义 new

Bil*_*ill 3 oop constructor julia

我是 Julia 的新手,正在尝试从本文复制的一些代码。它应该是在 Julia 中进行面向对象编程(即类)的一种方法:

\n
using Lathe.stats: mean, std\n\nstruct NormalDistribution{P}\n    mu::Float64\n    sigma::Float64\n    pdf::P\nend\n\nfunction NormalDistribution(x::Array)\n        pdf(xt::Array) = [i = (i-\xce\xbc) / \xcf\x83 for i in xt]\n        return new{typeof(pdf)}(mean(x), std(x), pdf)\nend\n\nx = [5, 10, 15, 20]\ndist = NormalDistribution(x)\n
Run Code Online (Sandbox Code Playgroud)\n

但是,当我在 Jupiter 笔记本中使用 Julia 1.1.1 运行此命令时,出现以下异常:

\n
UndefVarError: new not defined\n\nStacktrace:\n [1] NormalDistribution(::Array{Int64,1}) at ./In[1]:11\n [2] top-level scope at In[1]:15\n
Run Code Online (Sandbox Code Playgroud)\n

我在内部构造函数方法上找到了这个文档页面,它解释了它们有

\n
\n

一个特殊的本地存在函数,称为new创建块类型的对象。

\n
\n

(尽管上面链接的文档new说它是一个关键字)。

\n

我可能错误地复制了代码,但也许有人可以解释如何实现原作者在文章中提出的建议。另外,我还不知道如何在 Julia 中进行调试,所以任何指针都会受到赞赏。

\n

ffe*_*tte 5

您链接到的文档页面的意思是该new关键字仅存在于内部构造函数中(而不是外部构造函数)。

\n

因此,要么选择外部构造函数,在这种情况下,您想要使用默认构造函数来实际创建新实例:

\n
using Statistics\n\n# First the type declaration, which comes with a default constructor\nstruct NormalDistribution{P}\n    mu::Float64\n    sigma::Float64\n    pdf::P\nend\n\n# Another outer constructor\nfunction NormalDistribution(x::Array)\n    \xce\xbc = mean(x)\n    \xcf\x83 = std(x)\n    pdf(xt::Array) = [(i-\xce\xbc) / \xcf\x83 for i in xt]\n\n    # This is a call to the constructor that was created for you by default\n    return NormalDistribution(\xce\xbc, \xcf\x83, pdf)\nend\n
Run Code Online (Sandbox Code Playgroud)\n
julia> x = [5, 10, 15, 20]\n4-element Array{Int64,1}:\n  5\n 10\n 15\n 20\n\njulia> dist = NormalDistribution(x)\nNormalDistribution{var"#pdf#2"{Float64,Float64}}(12.5, 6.454972243679028, var"#pdf#2"{Float64,Float64}(12.5, 6.454972243679028))\n\njulia> dist.pdf([1, 2, 3])\n3-element Array{Float64,1}:\n -1.781572339255412\n -1.626653005407115\n -1.4717336715588185\n
Run Code Online (Sandbox Code Playgroud)\n

请注意,原文章中的定义pdf显然是有问题的(如果只是因为 \xce\xbc 和 \xcf\x83 没有定义)。我尝试修改它,使其有意义

\n

一个可能的问题是任何人都可以定义NormalDistribution状态不一致的实例:

\n
julia> NormalDistribution(0., 1., x->x+1)\nNormalDistribution{var"#11#12"}(0.0, 1.0, var"#11#12"())\n
Run Code Online (Sandbox Code Playgroud)\n

这就是为什么您可能想要实际定义一个内部构造函数,在这种情况下,Julia 不会为您提供默认构造函数,但您可以访问该特殊new函数,该函数创建您正在定义的类型的对象:

\n
# A type declaration with an inner constructor\nstruct NormalDistribution2{P}\n    mu::Float64\n    sigma::Float64\n    pdf::P\n\n    # The inner constructor is defined inside the type declaration block\n    function NormalDistribution2(x::Array)\n        \xce\xbc = mean(x)\n        \xcf\x83 = std(x)\n        pdf(xt::Array) = [(i-\xce\xbc) / \xcf\x83 for i in xt]\n\n        # Use the `new` function to actually create the object\n        return new{typeof(pdf)}(\xce\xbc, \xcf\x83, pdf)\n    end\nend\n
Run Code Online (Sandbox Code Playgroud)\n

它的行为方式与具有外部构造函数的结构完全相同,只是这次不再提供默认构造函数:

\n
julia> dist2 = NormalDistribution2(x)\nNormalDistribution2{var"#pdf#5"{Float64,Float64}}(12.5, 6.454972243679028, var"#pdf#5"{Float64,Float64}(12.5, 6.454972243679028))\n\njulia> dist2.pdf([1, 2, 3])\n3-element Array{Float64,1}:\n -1.781572339255412\n -1.626653005407115\n -1.4717336715588185\n\n# No default constructor provided\njulia> NormalDistribution2(0., 1., x->x+1)\nERROR: MethodError: no method matching NormalDistribution2(::Float64, ::Float64, ::var"#9#10")\nStacktrace:\n [1] top-level scope at REPL[13]:1\n
Run Code Online (Sandbox Code Playgroud)\n