在我的代码中,出于某些目的,我在函数名前使用了下划线(例如_foo()
),但想知道这是否可能产生副作用,例如干扰从基本库导出的函数。例如,我看到类似
ERROR: LoadError: ...
Stacktrace:
[1] _printf(::String, ::Expr, ::String, ::Tuple{Symbol,Expr,Symbol,Expr}) at ./printf.jl:1209
...
[7] _start() at ./client.jl:432
尽管我猜这些是库中的内部函数(未导出),但是使用这样的领先下划线作为用户定义函数是否安全(至少在仅使用标准库时)?
答案 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
这里sin
和cos
都是从Base
导入的。在使用之前,您已经在模块sin
中定义了Main
,这样就可以了。但是,在尝试定义之前,您使用了cos
中的Base
,所以这是一个错误。