带前导下划线的函数名称

roy*_*vib 2 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
Run Code Online (Sandbox Code Playgroud)

虽然我猜这些是库中的内部函数(未导出),但对用户定义的函数使用这样的前导下划线是否安全(至少在仅使用标准库时)?

Bog*_*ski 5

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

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

_通常不会导出带有前导的名称。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