(问题是指 Julia 版本 v1.5)
我试图了解@deprecate宏在 Julia 中的工作原理。该文档是不幸的是没有明确对我说:
@deprecate old new [ex=true]弃用旧方法并指定替换调用新方法。通过将 ex 设置为 false 来防止 @deprecate 导出旧的。@deprecate 定义了一个与旧方法具有相同签名的新方法。
警告:从 Julia 1.5 开始,@deprecate 定义的函数在没有设置 --depwarn=yes 标志的情况下运行 julia 时不会打印警告,因为 --depwarn 选项的默认值为 no。警告是从 Pkg.test() 运行的测试中打印出来的。
例子
julia> @deprecate old(x) new(x)旧(具有 1 个方法的通用函数)
julia> @deprecate old(x) new(x)假旧(具有 1 个方法的通用函数)
那我该怎么办?
function old(x::Int)
print("Old behavior")
end
function new(x::Int)
print("New behavior")
end
# Adding true/false argument doesn't change my observations.
@deprecate old(x) new(x) # false
old(3)
# Prints "Old behaviour". No warning.
# Also: The deprecation is not mentioned in the help (julia>? old)
Run Code Online (Sandbox Code Playgroud)
这个@deprecate宏的目的似乎是替换函数?我觉得这违反直觉。如何将一个函数标记为已弃用(即用户应该收到警告和提示使用什么作为替代,也应该在文档中)?
编辑:我注意到我的错误。签名(在我的情况下::Int)必须相同才能工作。但是,我如何收到警告?
想象一下,您将此方法作为版本 1 中库的公共 API 的一部分:
# v1.0.0
mult3(x::Int) = 3x
Run Code Online (Sandbox Code Playgroud)
在版本 2 中,您希望停止支持mult3(这是一个重大更改)。但是使用更通用的方法仍然可以使用相同的功能:
# v2.0.0
mult(x, y) = x * y
Run Code Online (Sandbox Code Playgroud)
版本 1 的用户习惯使用mult3,这意味着当他们更新到 v2 时,他们的代码会中断。因此,您可能希望发布 v1.x 系列中的中间版本,其中mult3存在但已弃用并在以下方面实施mult:
# v1.1 - transition
# This is the new API for v2
mult(x, y) = x*y
# The old API is still supported, but deprecated and implemented using the old one
@deprecate mult3(x::Int) mult(3, x)
# The above is more or less equivalent to defining
# function mult3(x::Int)
# # print an error message is `--depwarn` has been set
# return mult(3, x)
# end
Run Code Online (Sandbox Code Playgroud)
v1 API 在 v1.x 的后期版本中没有被破坏,但是调用已弃用方法的用户将看到以下类型的消息,以帮助他们过渡到较新的 v2 API:
julia> mult3(14)
? Warning: `mult3(x::Int)` is deprecated, use `mult(3, x)` instead.
? caller = top-level scope at REPL[3]:1
? @ Core REPL[3]:1
42
Run Code Online (Sandbox Code Playgroud)
(但从 Julia 1.5 开始,只有--depwarn=yes在 Julia 的命令行中提供或出现在由 运行的测试套件中时才会显示警告Pkg.test())
或者,正如评论中提到的,您可能希望保留旧的实现,只需在用户调用它时警告用户。为此,您可以Base.depwarn直接使用:
# v1.1 - transition
# This is the new API for v2
mult(x, y) = x*y
# The old API is still supported, but deprecated
# It is implemented by itself:
function mult3(x)
Base.depwarn("`mult3(x)` is deprecated, use `mult(3,x)` instead.", :mult3)
return 3x
end
Run Code Online (Sandbox Code Playgroud)
当--depwarn=yes已在 Julia 的命令行中提供时,会产生与以下相同类型的警告@deprecate:
julia> mult3(14)
? Warning: `mult3(x)` is deprecated, use `mult(3,x)` instead.
? caller = top-level scope at REPL[4]:1
? @ Core REPL[4]:1
42
Run Code Online (Sandbox Code Playgroud)
从 Julia 1.6 开始,depwarn将接受关键字参数以强制发出警告,即使用户没有要求它们--depwarn=yes:
julia> Base.depwarn("Foo is deprecated", :foo, force=true)
? Warning: Foo is deprecated
? caller = ip:0x0
? @ Core :-1
Run Code Online (Sandbox Code Playgroud)