fortranderived-typesassociate

A more efficient way to directly use member variables of a derived type without using the percentage sign


As shown in using fortran derived type variable without %, we can use associate to avoid using the percentage sign. An example is as below:

    program test
    type z_type
    real x,y
    end type z_type
    type(z_type) :: z
    associate (x=>z%x)
    associate (y=>z%y)
    x=10
    y=10
    write(6,*)z%x,z%y
    end associate
    end associate
    end

But if I have too many member variables in the derived type, are there any "efficient " way for me to get what the above "associate " approach does?
Thanks. An update: the problem is that I am refactoring a legacy code, in which I need to wrap up many variables to a derived type structure. But I hope I don't need to add to each variable in the block of the previous codes with the derived data name followed by % sign.


Solution

  • Well, you could use pointers, I suppose, but it's a bit unnatural.

    program test
       implicit none
    
       type z_type
          real x, y
       end type z_type
    
       type(z_type), target :: z
       real, pointer :: x, y
    
       x => z%x
       y => z%y
    
       x = 10
       y = 20
    
       write( *, * ) z
    
    end program test
    

    If the variables were all of one type then Fortran arrays are devastatingly effective:

    program test
       implicit none
    
       type z_type
          real x(2)
       end type z_type
    
       type(z_type) z
       z%x = [ 10, 20 ]
    
       write( *, * ) z
    
    end program test
    

    Overall, it might be better to make z_type a proper class, with its own type-bound procedures (aka member functions) and just make it object-oriented programming.

    module modz
       implicit none
    
       type z_type
          real x, y
       contains
          procedure write_me
       end type z_type
    
    contains
    
       subroutine write_me( this )
          class(z_type), intent(in) :: this
          write( *, *) this%x, this%y
       end subroutine write_me
    
    end module modz
    
    !=======================================
    
    program test
       use modz
       implicit none
    
       type(z_type) :: z = z_type( 10, 20 )
       call z%write_me
    
    end program test