为什么这里有一个红色的警告类型?

maf*_*afu 2 julia

我在以下 Julia 1.8 代码中收到红色警告

\n
mutable struct S\n    X::Int32\n    const Children::Vector{Ref{S}}\nend\n\nfunction f2(s::Ref{S})\n    x = Int32(0)\n    \n    chs = s[].Children\n    for ch in chs\n        add = ch[].X\n        x += add\n    end\n\n    println("f2: $(x)")\nend\n\nfunction test()\n    s = S(3, Vector{Ref{S}}())\n    @code_warntype f2(Ref{S}(s))\nend\ntest()\n
Run Code Online (Sandbox Code Playgroud)\n

输出:

\n
MethodInstance for f2(::Base.RefValue{S})\n  from f2(s::Ref{S}) in Main at example.jl:7\nArguments\n  #self#::Core.Const(f2)\n  s::Base.RefValue{S}\nLocals\n  @_3::Union{Nothing, Tuple{Ref{S}, Int64}}      (green)\n  chs::Vector{Ref{S}}\n  x::Any        (red)\n  ch::Ref{S}    (red)\n  add::Any      (red)\nBody::Nothing\n1 \xe2\x94\x80       (x = Main.Int32(0))\n\xe2\x94\x82   %2  = Base.getindex(s)::S      \n\xe2\x94\x82         (chs = Base.getproperty(%2, :Children))\n\xe2\x94\x82   %4  = chs::Vector{Ref{S}}\n\xe2\x94\x82         (@_3 = Base.iterate(%4))\n\xe2\x94\x82   %6  = (@_3 === nothing)::Bool\n\xe2\x94\x82   %7  = Base.not_int(%6)::Bool\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80       goto #4 if not %7\n2 \xe2\x94\x84 %9  = @_3::Tuple{Ref{S}, Int64}            (red)\n\xe2\x94\x82         (ch = Core.getfield(%9, 1))      \n\xe2\x94\x82   %11 = Core.getfield(%9, 2)::Int64      \n\xe2\x94\x82   %12 = Base.getindex(ch)::Any               (red)\n\xe2\x94\x82         (add = Base.getproperty(%12, :X))\n\xe2\x94\x82         (x = x + add)\n\xe2\x94\x82         (@_3 = Base.iterate(%4, %11))    \n\xe2\x94\x82   %16 = (@_3 === nothing)::Bool\n\xe2\x94\x82   %17 = Base.not_int(%16)::Bool\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80       goto #4 if not %17\n3 \xe2\x94\x80       goto #2\n4 \xe2\x94\x84 %20 = Base.string("f2: ", x)::String        \n\xe2\x94\x82   %21 = Main.println(%20)::Core.Const(nothing)\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80       return %21\n
Run Code Online (Sandbox Code Playgroud)\n

据我所知, 的类型ch可以在编译时确定。\n应该没有歧义。

\n

Bog*_*ski 5

Ref是抽象的。使用Base.RefValue它的具体子类型,因为这可能是您想要的:

\n
julia> mutable struct S\n           X::Int32\n           const Children::Vector{Base.RefValue{S}}\n       end\n\njulia> function f2(s::Ref{S})\n           x = Int32(0)\n\n           chs = s[].Children\n           for ch in chs\n               add = ch[].X\n               x += add\n           end\n\n           println("f2: $(x)")\n       end\nf2 (generic function with 1 method)\n\njulia> function test()\n           s = S(3, Vector{Ref{S}}())\n           @code_warntype f2(Ref{S}(s))\n       end\ntest (generic function with 1 method)\n\njulia> test()\nMethodInstance for f2(::Base.RefValue{S})\n  from f2(s::Ref{S}) @ Main REPL[11]:1\nArguments\n  #self#::Core.Const(f2)\n  s::Base.RefValue{S}\nLocals\n  @_3::Union{Nothing, Tuple{Base.RefValue{S}, Int64}}\n  chs::Vector{Base.RefValue{S}}\n  x::Int32\n  ch::Base.RefValue{S}\n  add::Int32\nBody::Nothing\n1 \xe2\x94\x80       (x = Main.Int32(0))\n\xe2\x94\x82   %2  = Base.getindex(s)::S\n\xe2\x94\x82         (chs = Base.getproperty(%2, :Children))\n\xe2\x94\x82   %4  = chs::Vector{Base.RefValue{S}}\n\xe2\x94\x82         (@_3 = Base.iterate(%4))\n\xe2\x94\x82   %6  = (@_3 === nothing)::Bool\n\xe2\x94\x82   %7  = Base.not_int(%6)::Bool\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80       goto #4 if not %7\n2 \xe2\x94\x84 %9  = @_3::Tuple{Base.RefValue{S}, Int64}\n\xe2\x94\x82         (ch = Core.getfield(%9, 1))\n\xe2\x94\x82   %11 = Core.getfield(%9, 2)::Int64\n\xe2\x94\x82   %12 = Base.getindex(ch)::S\n\xe2\x94\x82         (add = Base.getproperty(%12, :X))\n\xe2\x94\x82         (x = x + add)\n\xe2\x94\x82         (@_3 = Base.iterate(%4, %11))\n\xe2\x94\x82   %16 = (@_3 === nothing)::Bool\n\xe2\x94\x82   %17 = Base.not_int(%16)::Bool\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80       goto #4 if not %17\n3 \xe2\x94\x80       goto #2\n4 \xe2\x94\x84 %20 = Base.string("f2: ", x)::String\n\xe2\x94\x82   %21 = Main.println(%20)::Core.Const(nothing)\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80       return %21\n
Run Code Online (Sandbox Code Playgroud)\n