Julia中可变结构体数组赋值报UndefRefError错误是什么原因?
错误原因
- Julia中使用
undef初始化自定义结构体数组时,仅会分配数组的内存空间,不会为每个数组位置自动生成合法的结构体实例,此时数组内所有元素都处于未定义状态,直接访问元素的字段就会触发UndefRefError错误。
解决方法
有两种常用的实现方案:
方案1:循环中逐个初始化结构体实例
先为每个数组位置构造完整的MPData实例,再进行字段修改操作,示例代码如下:
for MPNum in 1:TotalNumMP # 所有字段都传入合法初始值,无初始值可先填对应类型的占位符 MPDataArray[MPNum] = MPData{Float32}( 'M', # MPType初始值,可直接赋值为你需要的'M' ' ', # ConstModelType占位符 Float32[], # MPCoords初始空数组,可替换为你的实际初始值 0.0f0, # MPVol初始值 0.0f0, # MPInitVol初始值 0.0f0, # MPMass初始值 UInt32[], # MPNodes初始空数组 UInt32[], # MPEls初始空数组 UInt32(0), # NumStiffMatEntries初始值 Float32[], # BasisFns初始空数组 Float32[], # BasisFnsDerivs初始空数组 Float32[], # PrevDefGrad初始空数组 Float32[], # CurrentDefGrad初始空数组 Float32[], # CauchyStress初始空数组 Float32[], # PrevElasticStrain初始空数组 Float32[], # CurrentElasticStrain初始空数组 MatParams(),# 此处需传入MatParams类型的合法实例 Float32[], # PointForces初始空数组 Float32[] # Displacement初始空数组 ) # 实例初始化完成后可自由修改任意字段 end
方案2:为结构体定义默认构造函数简化初始化
如果需要频繁创建该结构体实例,可以在结构体定义时新增默认构造函数,减少重复代码:
mutable struct MPData{T} MPType::Char ConstModelType::Char MPCoords::Array{T} MPVol::T MPInitVol::T MPMass::T MPNodes::Array{UInt32} MPEls::Array{UInt32} NumStiffMatEntries::UInt32 BasisFns::Array{T} BasisFnsDerivs::Array{T} PrevDefGrad::Array{T} CurrentDefGrad::Array{T} CauchyStress::Vector{T} PrevElasticStrain::Vector{T} CurrentElasticStrain::Vector{T} MatConsts::MatParams PointForces::Array{T} Displacement::Array{T} # 新增默认构造函数 MPData{T}() where T = new{T}( ' ', ' ', T[], zero(T), zero(T), zero(T), UInt32[], UInt32[], UInt32(0), T[], T[], T[], T[], T[], T[], T[], MatParams(), T[], T[] ) end
之后直接用列表生成式初始化数组即可,不需要再手动填每个字段的初始值:
# 生成的数组内每个位置都是独立的合法MPData实例 MPDataArray = [MPData{Float32}() for _ in 1:TotalNumMP]
此时你原本的字段赋值代码就可以正常运行了。
注意事项
不要使用fill(MPData{Float32}(), TotalNumMP)初始化数组,该方式只会创建1个MPData实例,数组所有位置都指向同一个实例,修改任意一个元素的字段都会同步影响所有元素。
内容的提问来源于stack exchange,提问作者user16570427
相关产品推荐
相关产品推荐

