【发布时间】:2019-10-09 13:45:01
【问题描述】:
作为一名老 C 程序员,我在代码中使用了很多断言。现在我想全局关闭它们以加快速度。这样做的最佳做法是什么?
【问题讨论】:
-
这确实是应该加的,但是目前没有这个flag。
作为一名老 C 程序员,我在代码中使用了很多断言。现在我想全局关闭它们以加快速度。这样做的最佳做法是什么?
【问题讨论】:
目前还没有内置选项/命令行标志来全局禁用@asserts(!)。
现在,您可以定义一个 @myassert 宏,根据全局开关,它是无操作或常规 @assert:
asserting() = false # when set to true, this will enable all `@myassert`s
macro mayassert(test)
esc(:(if $(@__MODULE__).asserting()
@assert($test)
end))
end
f(x) = @mayassert x < 2
(取自https://discourse.julialang.org/t/assert-alternatives/24775/14)
【讨论】:
虽然拥有此功能会很好,但可以通过定义和调度您自己的类型来减少代码中对@asserts 的需求。例如,假设您有一个函数foo(t::TimeType) = t,但您只想接受五分钟的倍数。您可以根据此要求创建新类型:
using Dates
struct FiveMinuteMultiple
t::DateTime
function FiveMinuteMultiple(y, m, d, h, mi)
if mi%5 != 0
throw(DomainError(m, "the minute argument must be a multiple of 5"))
end
new(DateTime(y, m, d, h, mi))
end
end
现在您实际上无法创建不是五分钟倍数的FiveMinuteMultiple:
julia> t = FiveMinuteMultiple(2016, 7, 15, 4, 23)
ERROR: DomainError with 7:
the minute argument must be a multiple of 5
Stacktrace:
[1] FiveMinuteMultiple(::Int64, ::Int64, ::Int64, ::Int64, ::Int64) at ./REPL[2]:5
[2] top-level scope at none:0
julia> t = FiveMinuteMultiple(2016, 7, 15, 4, 25)
FiveMinuteMultiple(2016-07-15T04:25:00)
因此,如果您现在定义 foo(t::FiveMinuteMultiple) = t,则不再需要 @assert 来验证参数是五分钟的倍数。当然,当您构造 FiveMinuteMultiple 时,您仍然需要支付参数检查的成本,但除非它是一个热内循环,否则您可能无论如何都需要额外的数据验证。
优点:
foo(t::FiveMinuteMultiple)、bar(t::FiveMinuteMultiple) 和baz(t::FiveMinuteMultiple) 之间重复相同的断言。缺点:
FiveMinuteMultiple,您可能需要将day、hour 等方法转发到结构的t 字段。【讨论】:
您可以将@assert 语句放在@debug 块中。然后 @assert 调用将被停用,除非您在全局 (ENV["JULIA_DEBUG"] = "all") 或仅为您的模块 (ENV["JULIA_DEBUG"] = "NameOfYourModule") 激活调试
julia> @debug begin
@assert 1==2
end
#or
@debug @assert 1==2 # assert is not called
julia> ENV["JULIA_DEBUG"] = "all" # enable debugging
"all"
julia> @debug begin
@assert 1==2
end
┌ Error: Exception while generating log record in module Main at REPL[4]:1
│ exception =
│ AssertionError: 1 == 2
│ Stacktrace:
│ [1] top-level scope at REPL[4]:2
│ [2] top-level scope at logging.jl:319
| ...
└ @ Main REPL[4]:1
【讨论】:
Error: Exception while generating log record in module。