在我的代码中,我使用带有前导下划线的函数名称,例如_foo()出于某些目的,但想知道这是否可能产生副作用,例如,干扰从基本库导出的函数。例如,我看到类似的错误消息
ERROR: LoadError: ...
Stacktrace:
[1] _printf(::String, ::Expr, ::String, ::Tuple{Symbol,Expr,Symbol,Expr}) at ./printf.jl:1209
...
[7] _start() at ./client.jl:432
Run Code Online (Sandbox Code Playgroud)
虽然我猜这些是库中的内部函数(未导出),但对用户定义的函数使用这样的前导下划线是否安全(至少在仅使用标准库时)?
通常以下划线开头的名称用于内部函数或变量,但这只是一种风格约定。在您自己的代码中使用它们是安全的,但以下规则除外:
仅由下划线组成的名称,如_或__用作黑洞(您可以写入它们,但不能从中读取)。
_通常不会导出带有前导的名称。Base 中的一个例外是__precompile__函数。
下面我给出了更一般的评论,但与您所问的内容相关,并且根据我的经验,值得了解它。
函数和变量名称是在模块作用域中定义的,这意味着如果您创建自己的模块,您可以使用与其他模块中的相同名称冲突的名称,这不会成为问题(无论您在模块中是否有前导下划线)无论是否)。您只需限定该名称即可:
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)"
Run Code Online (Sandbox Code Playgroud)
通常棘手的唯一极端情况是,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
Run Code Online (Sandbox Code Playgroud)
这里 和sin都是cos从 导入的Base。您在使用之前sin在模块中定义了Main它,所以没问题。但是,您在尝试定义它之前使用了cosfrom ,因此这是一个错误。Base