【问题标题】:Julia unexpacted behavior: function definition inside if elseif end fails or returns wrong resultJulia 意外行为:如果 elseif end 失败或返回错误结果,则内部函数定义
【发布时间】:2021-02-04 12:25:08
【问题描述】:

我有几个函数使用不同的方法计算同一件事。我现在想将它们捆绑在一个主函数中,并带有一个用于选择方法的关键字参数。我想出的结构看起来……像下面的最小示例。这背后的想法是将特定函数分配给通用函数名称,因为它在函数内部多次使用,我不想在多个地方使用 if else .. 结构。

function testfun(input::Real; method::String = "a")
    if method == "a"
        println("Method a was chosen")
        calculate(x) = 2x # in the real code methods are assigned here, but the errors are the same
    elseif method == "b"
        println("Method b was chosen")
        calculate(x) = 3x
    else
        throw(DomainError(method))
    end
    return calculate(input)
end

但是这段代码不像预期的那样工作并生成:

testfun(1) # -> 3, but expected 2
testfun(1, method = "a") # -> 3, but expected 2
testfun(1, method = "b") # -> ERROR: UndefVarError: calculate not defined, but expected 3
testfun(1, method = "c") #  throws the correct DomainError

当 println() 正确触发时,我在这里缺少什么来解释这种行为? Julia 版本是 1.5。 构建此类函数的正确/最佳方法是什么?

【问题讨论】:

标签: julia


【解决方案1】:

当我将它直接粘贴到 REPL 中时,我得到了这个:WARNING: Method definition calculate(Any) in module Main at REPL[35]:4 overwritten at REPL[35]:7. 看起来由于某种原因,只会使用 calculate 的最后一个定义。

你可以使用calculate = x -> 2x这样的匿名函数:

function testfun(input::Real; method::String = "a")
    if method == "a"
        println("Method a was chosen")
        calculate = x -> 2x # in the real code methods are assigned here, but the errors are the same
    elseif method == "b"
        println("Method b was chosen")
        calculate = x -> 3x
    else
        throw(DomainError(method))
    end
    return calculate(input)
end

输出:

julia> testfun(1)
Method a was chosen
2

julia> testfun(1; method="b")
Method b was chosen
3

【讨论】:

  • 见:github.com/JuliaLang/julia/issues/15602。在 Julia 1.6 及更高版本中,这给出了您提到的警告。
  • @fredrikekre,所以它现在被提升为错误 - 比警告好得多
  • 不,这是一个警告。
  • @fredrikekre,有人写了pull request 来使这个错误。但是,似乎还没有达成共识……
  • 是的,我知道,但无论如何这不会进入 Julia 1.6,所以现在这是一个警告。
猜你喜欢
  • 1970-01-01
  • 2011-05-19
  • 1970-01-01
  • 1970-01-01
  • 2011-12-02
  • 1970-01-01
  • 2021-01-16
  • 2023-02-23
  • 2015-05-29
相关资源
最近更新 更多