使用Fortran 95。
我需要使用无格式写入序列化复杂的派生类型(包含其他派生类型)(随后使用未格式化的读取来重新加载它)。
最简单就是
write(lun) myComplexType
但是这不起作用,因为该类型包含指针。我并不担心保留指针(我可以单独序列化它指向的内容并在以后重新加载时重新建立指针)。
因为派生类型的结构易于更改,所以我希望避免在主代码或定义的输出过程中单独编写每个元素。
是否有一种简单的方法可以执行无格式写入,忽略指针,并且不需要我单独处理许多其他嵌套数据元素 - 这会给我一个维护问题?
如果没有一种简单的方法,我可能不得不将指针放在一个单独的并行数据结构中,但我对此并不满意,因为我需要确保它们不会分离或不同步时作为参数传递(所讨论的结构保持复杂模拟的状态,我真的希望将整个状态保持在一个结构中)。
基本目的只是将模拟状态序列化为文件间隔,以便稍后我可以从状态的序列化转储中重新启动模拟。
答案 0 :(得分:3)
一种方法是将非指针组件拆分为它们自己的类型,然后将其用作另一个“包装器”类型的组件类型,该类型也包含指针。
TYPE :: non_pointer
! Lots of non-pointer components/nested types, etc.
END TYPE non_pointer
TYPE :: wrapper
TYPE(non_pointer) :: stuff
TYPE(xxx), POINTER :: ptr_comp
END TYPE wrapper
您的输入/输出语句然后引用stuff
组件。
TYPE(wrapper) :: my_simulation_state
WRITE (unit) my_simulation_state%stuff
程序通常对包装类型的对象进行操作,这仍然将“整个状态”保留在一个结构中。
是否合适取决于从现有类型中提取指针组件的容易程度。
答案 1 :(得分:1)
受到Ian的回答的启发,考虑继承来分离非指针和指针数据并仅写入基本部分可能会很有趣。 (但在实践中,组合方法可能更灵活和推荐(例如this page))。
program main
implicit none
type simbase_t !! includes all non-pointer data
integer :: n = 0
real :: x = 0.0
endtype
type, extends(simbase_t) :: sim_t !! for additional pointer data
integer, pointer :: p => null()
endtype
type(sim_t) :: sim1, sim2
sim1 % n = 100
sim1 % x = 1.23
print *, "sim2 (before) = ", sim2 % simbase_t
write( 100 ) sim1 % simbase_t
rewind( 100 )
read( 100 ) sim2 % simbase_t
print *, "sim2 (after) = ", sim2 % simbase_t
end program
结果:
sim2 (before) = 0 0.0000000
sim2 (after) = 100 1.2300000