function - 在 Julia 的函数作用域内的 if 语句内定义函数的结果错误

标签 function if-statement scope julia compiler-warnings

我觉得有点奇怪,它在全局范围内工作得很好,但在函数作用域内,编译器会在 ifelse 语句中定义一个函数,我将其显式设置为 false。

尽管如此,是否有任何标准可以防止这种困惑,这种现象背后的底层编译逻辑是什么?

我不确定,但我想这个问题可能与Conditionally define a function inside another function in Julia有关.

我进行了这个简单的实验。最初,我在全局范围内定义了实验,一切都按预期进行。但是,当我在函数作用域内运行相同的代码片段时,输出似乎受到 ifelse 语句的影响,尽管它被设置为 false。

# weird.jl
function experiment()
    g(x) = 0
    if ( true )
        println("Here")
        g(x) = 0
    elseif (false)
        g(x) = 1
    end
    println("We expect g(1) == 0, and we get g(1) ==", g(1))
end

g(x) = 0
if (true)
    println("Here")
    g(x) = 0
elseif (false)
    g(x) = 1
end
println("We expect g(1) == 0, and we get g(1) ==", g(1))


println("\nExperiment")
experiment()

带输出

WARNING: Method definition g(Any) in module Main at /root/code/weird.jl:3 overwritten at /root/code/weird.jl:6.
WARNING: Method definition g(Any) in module Main at /root/code/weird.jl:6 overwritten at /root/code/weird.jl:8.
Here
We expect g(1) == 0, and we get g(1) ==0

Experiment
Here
We expect g(1) == 0, and we get g(1) ==1

关于申请。对我来说,总体目标是能够定义这样的函数

function lots_of_computations(mode)
    # Defining variables and computations ....
    if ( mode==Physical )
        g_0(x, t) = 0
        g_1(x) = 0
        g_2(x,t) = 0
    elseif (mode==General)
        g_0(x, t) = 2*ε*sin(2π*t/(100*τ))*sin(2π*x[1]/L)*cos(2π*x[2]/L)
        g_1(x) =  ε*x[1]
        g_2(x,t) =  ε*t*x[2]
    else
        println("not supported")
    end

    # More computations ....
end

但是,这似乎在函数作用域中无法可靠地工作。

最佳答案

正如 https://github.com/JuliaLang/julia/issues/15602 中所解释的那样(在您看到的 Conditionally define a function inside another function in Julia 中链接)当前推荐且安全的实现您想要的方法是使用匿名函数,因此您的代码可以看起来例如像:

function lots_of_computations(mode)
    # Defining variables and computations ....
    if mode isa Physical
        g_0 = (x, t) -> 0
        g_1 = x -> 0
        g_2 = (x,t) -> 0
    elseif mode isa General
        g_0 = (x, t) -> 2*ε*sin(2π*t/(100*τ))*sin(2π*x[1]/L)*cos(2π*x[2]/L)
        g_1 = x ->  ε*x[1]
        g_2 = (x,t) ->  ε*t*x[2]
    else
        println("not supported")
    end

    # More computations ....
end

请注意,我将 mode==Physical 更改为 mode isa Physical,以便条件取决于 mode 的类型而不是其值。原因是在这种情况下,if 语句将在编译期间被优化。 mode==Physical 条件通常也可以被优化(感谢编译器中的不断传播),但不能保证情况总是如此,因此通常最好这样做基于类型而不是参数值的条件。

关于function - 在 Julia 的函数作用域内的 if 语句内定义函数的结果错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77260725/

相关文章:

python-3.x - python : How do I alias a function with specific parameters?

python - 将函数绑定(bind)到 Kivy 按钮

python for循环只执行一次?

javascript - VueJS 条件排序数据到表

javascript - AngularJS 范围未定义

Java:修改不带参数的变量

python - Pandas : local vs global dataframe in functions

c++ - Boost::Variant and function_types in it: How to put functions into Boost::variant?

python - Python 选择文本游戏出现问题(if-then 语句无法正常工作)

java - Java中的变量作用域