是否有理由在 if VERSION 语句之前放置@static?

DVN*_*old 3 julia

比如前面这个:

@static if v"0.2" <= VERSION < v"0.3-"
    # do something specific to 0.2 release series
end
Run Code Online (Sandbox Code Playgroud)

@static有必要吗?

Ste*_*ski 6

除了@DVNold 的答案之外,这里还有更多解释......

\n

一、两者的区别:

\n
    \n
  • if在全局范围内,条件和选择的任何分支都会在该代码运行时进行评估;
  • \n
  • @static if在解析代码时(在宏扩展期间)评估条件,并替换为条件选择的分支的代码 \xe2\x80\x94\xc2\xa0noif在宏扩展后留下。
  • \n
\n

在顶级全局范围中,这两者之间没有太大区别,因为评估仅发生一次,就在代码被解析、宏扩展和降低之后。然而,在某些情况下,您无法在语法上放置if表达式。一个很好的例子是,如果您希望结构中字段的存在或不存在以某些条件为条件:

\n
have_baz_field = rand(Bool)\n\nstruct Foo\n    bar::Int\n    @static if have_baz_field\n        baz::Int\n    end\nend\n
Run Code Online (Sandbox Code Playgroud)\n

以下是对该代码的两种不同的评估:

\n
julia> have_baz_field = rand(Bool)\nfalse\n\njulia> struct Foo\n           bar::Int\n           @static if have_baz_field\n               baz::Int\n           end\n       end\n\njulia> fieldnames(Foo)\n(:bar,)\n
Run Code Online (Sandbox Code Playgroud)\n
julia> have_baz_field = rand(Bool)\ntrue\n\njulia> struct Foo\n           bar::Int\n           @static if have_baz_field\n               baz::Int\n           end\n       end\n\njulia> fieldnames(Foo)\n(:bar, :baz)\n
Run Code Online (Sandbox Code Playgroud)\n

当然,随机有或没有字段并不是很有用;在实践中,您需要一个更有意义的条件来决定是否拥有该字段,这可能取决于您在尝试匹配 C 结构体布局时所使用的平台。

\n

if在本地范围内,和之间存在更多差异,@static if因为代码可以被评估多次,而它只能解析一次。由于条件是在表达式出现的全局范围内的解析时求值的,因此表单@static if无法访问任何局部变量,因为在扩展宏时它们不存在。另一方面,如果非静态 if 的条件仅基于全局常量,则编译器很有可能可以预测条件的值,因此仍然可能没有任何有效的差异,因为编译器将消除无论如何,除了所采取的分支之外的所有代码。但是,如果您想确保这种情况发生在解析/编译时,那么您可以使用@static if强制它。

\n

希望这能澄清其中的区别。简而言之,您很少需要@static if,因为它通常在顶级作用域甚至本地作用域中是等效的,在您可以使用@static if编译器的情况下,无论如何它可能已经执行了等效操作。在某些情况下,@static if由于语法上不允许分支,因此需要在全局范围内使用。在本地范围内,通常没有必要,但可能需要真正确保在运行时不评估条件。在大多数代码中,您不需要@static if. 例如,在问题中给出的示例中,我个人只会使用if并省略@static,因为表达式出现在顶层,并且无论哪种方式,条件仅计算一次。

\n