Struct Embedding in Fortran

module base_module
  implicit none
  private
  public :: base_type, describe

  type :: base_type
    integer :: num
  end type base_type

contains
  function describe(b) result(desc)
    type(base_type), intent(in) :: b
    character(:), allocatable :: desc
    character(len=20) :: num_str

    write(num_str, '(I0)') b%num
    desc = "base with num=" // trim(num_str)
  end function describe
end module base_module

module container_module
  use base_module
  implicit none
  private
  public :: container_type

  type :: container_type
    type(base_type) :: base
    character(:), allocatable :: str
  end type container_type
end module container_module

program struct_embedding
  use base_module
  use container_module
  implicit none

  type(container_type) :: co
  
  co%base%num = 1
  co%str = "some name"

  print '(A,I0,A,A)', "co={num: ", co%base%num, ", str: ", co%str

  print '(A,I0)', "also num: ", co%base%num

  print '(A,A)', "describe: ", describe(co%base)

  ! Fortran doesn't have interfaces like Go, so we'll simulate it with a procedure pointer
  print '(A,A)', "describer: ", describe(co%base)

end program struct_embedding

Fortran doesn’t have a direct equivalent to struct embedding as in Go, but we can achieve similar functionality using modules and derived types. Here’s an explanation of the Fortran code:

  1. We define a base_module that contains the base_type and the describe function.

  2. The container_module uses the base_module and defines a container_type that includes a base_type as a component.

  3. In the main program, we create a container_type variable and set its values.

  4. We can access the num field directly through the base component of the container_type.

  5. We can call the describe function with the base component of the container_type.

  6. Fortran doesn’t have interfaces like Go, so we can’t directly implement the describer interface. Instead, we simulate it by calling the describe function directly.

To run the program, save it as struct_embedding.f90 and compile it using a Fortran compiler:

$ gfortran struct_embedding.f90 -o struct_embedding
$ ./struct_embedding
co={num: 1, str: some name}
also num: 1
describe: base with num=1
describer: base with num=1

This Fortran code demonstrates a similar concept to struct embedding in Go, although the implementation details differ due to the language’s characteristics.