program main
use structs_module
implicit none
type(person) :: p1, p2, p3
type(person), pointer :: p_ptr
type :: dog
character(len=:), allocatable :: name
logical :: isGood
end type dog
type(dog) :: myDog
! This syntax creates a new struct.
p1 = person('Bob', 20)
print *, 'Name: ', p1%name, ', Age: ', p1%age
! You can name the fields when initializing a struct.
p2 = person(name='Alice', age=30)
print *, 'Name: ', p2%name, ', Age: ', p2%age
! Omitted fields will be zero-valued.
p3 = person(name='Fred')
print *, 'Name: ', p3%name, ', Age: ', p3%age
! An association yields a pointer to the struct.
allocate(p_ptr)
p_ptr = person(name='Ann', age=40)
print *, 'Name: ', p_ptr%name, ', Age: ', p_ptr%age
! It’s idiomatic to encapsulate new struct creation in constructor functions
p_ptr => newPerson('Jon')
print *, 'Name: ', p_ptr%name, ', Age: ', p_ptr%age
! Access struct fields with a dot.
print *, 'Name: ', p1%name
! You can also use dots with struct pointers - the pointers are manually dereferenced.
print *, 'Age: ', p_ptr%age
! Structs are mutable.
p_ptr%age = 51
print *, 'New Age: ', p_ptr%age
! Anonymous struct type
myDog = dog(name='Rex', isGood=.true.)
print *, 'Dog Name: ', myDog%name, ', Is Good: ', myDog%isGood
! Deallocate pointer
deallocate(p_ptr)
end program main