具有下划线的函数名称

时间:2018-12-08 23:23:28

标签: julia

在我的代码中,出于某些目的,我在函数名前使用了下划线(例如_foo()),但想知道这是否可能产生副作用,例如干扰从基本库导出的函数。例如,我看到类似

的错误消息
ERROR: LoadError: ...
Stacktrace:
 [1] _printf(::String, ::Expr, ::String, ::Tuple{Symbol,Expr,Symbol,Expr}) at ./printf.jl:1209
 ...
 [7] _start() at ./client.jl:432

尽管我猜这些是库中的内部函数(未导出),但是使用这样的领先下划线作为用户定义函数是否安全(至少在仅使用标准库时)?

1 个答案:

答案 0 :(得分:2)

通常,以下划线开头的名称用于内部函数或变量,但这只是一种样式约定。除了以下规则外,在您自己的代码中使用它们是安全的:

仅由下划线组成的名称(例如___)被用作黑洞(您可以对它们进行写入,但不能从中读取)。

通常不会导出前导_的名称。 __precompile__函数是Base中的一个例外。

下面我给出一个更笼统的评论,但与您的要求有关,根据我的经验,值得一听。

函数和变量名是在模块作用域中定义的,这意味着,如果您创建自己的模块,则可以在其他模块中使用与同一名称相冲突的名称,这不会出现问题(无论您是否拥有是否使用下划线)。您只需要限定名称即可:

julia> module MyModule
       export sin
       sin(x) = "sin($x)"
       end
Main.MyModule

julia> using .MyModule

julia> sin(1)
WARNING: both MyModule and Base export "sin"; uses of it in module Main must be qualified
ERROR: UndefVarError: sin not defined
Stacktrace:
 [1] top-level scope at none:0

julia> Base.sin(1)
0.8414709848078965

julia> MyModule.sin(1)
"sin(1)"

唯一棘手的情况通常是棘手的是,只有当该名称不是从其他模块中导入时,才允许在模块中定义自己的函数名称(尤其是在Main模块中)并引用到。这是一个示例:

julia> sin(x) = "sin($x)"
sin (generic function with 1 method)

julia> sin(10)
"sin(10)"

julia> cos(10)
-0.8390715290764524

julia> cos(x) = "cos($x)"
ERROR: error in method definition: function Base.cos must be explicitly imported to be extended
Stacktrace:
 [1] top-level scope at none:0

这里sincos都是从Base导入的。在使用之前,您已经在模块sin中定义了Main,这样就可以了。但是,在尝试定义之前,您使用了cos中的Base,所以这是一个错误。