Julia的struct能否定义字段维度匹配的持久校验规则?
实现方法
你可以通过重载Base.setproperty!函数实现字段赋值时的自动校验,这个函数会在你使用.语法给结构体字段赋值时自动触发,完整实现如下:
完整代码示例
mutable struct myStruct data::AbstractMatrix labels::Vector{String} # 保留初始化时的校验逻辑 function myStruct(data, labels) if length(labels) != size(data, 2) error("Labels incorrect length, expected $(size(data,2)), got $(length(labels))") end new(data, labels) end end # 重载字段赋值方法 function Base.setproperty!(obj::myStruct, field::Symbol, value) # 仅对labels字段做长度校验 if field == :labels # 注意这里要用getfield读取字段,避免触发setproperty!导致递归 data = getfield(obj, :data) if length(value) != size(data, 2) error("Labels incorrect length, expected $(size(data,2)), got $(length(value))") end end # 校验通过后完成实际赋值 setfield!(obj, field, value) end
效果测试
# 正常初始化 m = myStruct(randn(2,2), ["a", "b"]) # 尝试赋值长度不匹配的labels,会直接抛出错误 m.labels = ["a"] # 错误输出:Labels incorrect length, expected 2, got 1 # 赋值长度匹配的内容可正常执行 m.labels = ["c", "d"] @assert m.labels == ["c", "d"] # 验证赋值成功
注意事项
- 实现
setproperty!时必须用getfield/setfield读写结构体的底层字段,不要使用obj.field的语法,否则会递归调用setproperty!导致栈溢出。 - 如果需要支持修改
data字段时也自动校验长度,可在上述setproperty!方法中新增针对:data字段的校验分支,判断新的data列数是否和现有labels长度匹配即可。
内容的提问来源于stack exchange,提问作者DFL
相关产品推荐
相关产品推荐

