Julia 是否有理由将@static放在if版本语句之前?

Julia 是否有理由将@static放在if版本语句之前?,julia,Julia,例如,在此之前: @static if v"0.2" <= VERSION < v"0.3-" # do something specific to 0.2 release series end @static if v“0.2”是,在某些上下文中不允许使用if语句,但宏是,或者您不能在if语句中定义结构。在函数内部,它通常不是必需的,但有时您希望绝对确保if语句被消除。除了@DVNold的答案之外,这里还有更多的解释 首先,两者之间

例如,在此之前:

@static if v"0.2" <= VERSION < v"0.3-"
    # do something specific to 0.2 release series
end

@static if v“0.2”是,在某些上下文中不允许使用if语句,但宏是,或者您不能在if语句中定义结构。在函数内部,它通常不是必需的,但有时您希望绝对确保if语句被消除。

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

首先,两者之间的区别:

  • 如果
    在全局范围内,则在运行该代码时,将对条件和选择的任何分支进行评估
  • @static if
    在解析代码时(在宏扩展期间)计算条件,并用条件选择的任何分支的代码替换该条件-如果宏扩展后仍保留
,则无


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

have_baz_field = rand(Bool)

struct Foo
    bar::Int
    @static if have_baz_field
        baz::Int
    end
end
以下是对该代码的两种不同评估:

julia> have_baz_field = rand(Bool)
false

julia> struct Foo
           bar::Int
           @static if have_baz_field
               baz::Int
           end
       end

julia> fieldnames(Foo)
(:bar,)
当然,随机地有一个字段或没有字段不是很有用;在实践中,对于是否有字段,您可能希望有一个更有意义的条件,这可能是基于您在尝试匹配C结构布局时所处的平台

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


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

您可以在REPL中的if语句中定义结构,至少在我刚刚尝试过的1.5中。我想不出一个上下文中表达式是不允许的,但是一个宏返回一个表达式是不允许的。只有表达式。但是有些表达式只允许在顶层使用。您能提供一个代码示例或其他演示,说明为什么这个答案是正确的吗?当它不适用时?比如通过查看
@cose_键入的
来显示函数内部不需要它?
julia> have_baz_field = rand(Bool)
true

julia> struct Foo
           bar::Int
           @static if have_baz_field
               baz::Int
           end
       end

julia> fieldnames(Foo)
(:bar, :baz)