julia - Julia: How to use the @assert macro with a struct? @with_kw vs Base.@kwdef
问题描述
I want to use the @assert macro with a struct. The @with_kw macro from package Parameters
can be used with no explicit method built on top of the struct, whereas Base.@kwdef needs an explicit method. Did I understand this correctly?
# 1. outer constructor with "semi-colon" keyword + no keyword macro + @assert
struct myStruct1
a :: Float64
end
function myStruct1(;a::Float64=1.0)
@assert a > 0 "must be positive"
myStruct1(a)
end
myStruct1().a
## 1.0
myStruct1(a = -1.0).a
## ERROR: LoadError: AssertionError: must be positive
# 2.1. Base.@kwdef + no outer constructor + @assert
Base.@kwdef struct myStruct2
a :: Float64 = 1.0
@assert a > 0 "must be positive" # was hoping this would work
end
myStruct2().a
## ERROR: LoadError: UndefVarError: a not defined
# 2.2. Base.@kwdef + outer constructor + @assert
Base.@kwdef struct myStruct22
a :: Float64 = 1.0
end
function myStruct22(;a::Float64=1.0) # explicit method just to @assert
@assert a > 0 "must be positive"
myStruct22(a)
end
myStruct22().a
## 1.0
myStruct22(a = -1.0).a
## ERROR: LoadError: AssertionError: must be positive
# 2.3. @with_kw + outer constructor + @assert
using Parameters
@with_kw struct myStruct23
a :: Float64 = 1.0
@assert a > 0 "must be positive" # works without explicit method
end
myStruct23().a
## 1.0
myStruct23(a = -1.0).a
# ERROR: LoadError: AssertionError: must be positive
解决方案
Currently, Base.@kwdef
does not support that, since, as you said, it uses an outer constructor. You can check the generated code with @macroexpand
macro:
julia> @macroexpand Base.@kwdef struct myStruct2
a :: Float64 = 1.0
@assert a > 0 "must be positive" # was hoping this would work
end
quote
#= util.jl:472 =#
begin
$(Expr(:meta, :doc))
struct myStruct2
#= REPL[3]:2 =#
a::Float64
#= REPL[3]:3 =#
if a > 0
nothing
else
Base.throw(Base.AssertionError("must be positive"))
end
end
end
#= util.jl:473 =#
myStruct2(; a = 1.0) = begin
#= util.jl:450 =#
myStruct2(a)
end
end
As you see, the assert code in the struct definition but not in the outer constructor.
推荐阅读
- python - 有没有办法使用一个字典中的值来搜索另一个字典?
- python - 绘制图形时 xlim() 绝对被忽略
- python - 如何根据条件将现有数据帧的行推送到新数据帧?
- azure - 如何将 Azure Scaleset 添加到 Log Analytics
- java - 无法解析方法的 SparkSession(),我使用的依赖版本是 2.4.3
- micronaut - 如何让 Micronaut 使用从 Map 到 String 的自定义 TypeConverter?
- c++ - 为什么 'operator<<(cout, double)' 不起作用?
- java - 需要在java中获取linux环境参数值
- audio - 如果我使用不同采样率的音频数据集进行深度学习,会有什么问题吗?
- spring-boot - 在 Infinispan 中将可缓存注释与树缓存一起使用