我想做点什么:
(伪代码)
For all x in my_namelist_list
Read(unit_number,nml=x)
...
some other operations
...
end
名单的类型是什么?是否可以将其作为参数传递?
subroutine generic_reading_of_namelist(namelist_argument)
有人知道任何解决方法一起操作多个名单吗?
答案 0 :(得分:3)
简而言之:namelist没有类型,因为它是一个语句,而不是一个变量声明。这意味着它的使用非常有限:仅作为I / O操作的nml =
参数。
这也是一个非常古老的功能,如here所述,自推出以来,其功能几乎没有变化。
所以,最直接的取决于你想要做什么。例如,您可以尝试将一个名称列表用于多个目的,或者设计您自己的输入文件格式,并为其启用自定义读取例程。
编辑:
假设您有几个模块中的抽象类型和一些扩展:
module absTypeMod
implicit none
type, abstract :: absType
integer :: i = 0
contains
procedure(info), pass(this), public, deferred :: info
end type
abstract interface
subroutine info(this)
import :: absType
class(absType), intent(in) :: this
end subroutine
end interface
end module
module typeAMod
use absTypeMod
implicit none
type, extends(absType) :: typeA
private
integer :: j = 1
contains
procedure :: info => info_A
end type
contains
subroutine info_A(this)
class(typeA), intent(in) :: this
print*, 'i:', this%i, 'j:', this%j
end subroutine
end module
module typeBMod
use absTypeMod
implicit none
type, extends(absType) :: typeB
private
real :: k = 2.0
contains
procedure :: info => info_B
end type
contains
subroutine info_B(this)
class(typeB), intent(in) :: this
print*, 'i: ', this%i, ' k: ', this%k
end subroutine
end module
然后,您可以创建一个工厂模块,该模块提供基于某些输入实例化具体扩展的逻辑。一个例子:
module factoryMod
use typeAMod
use typeBMod
private
public :: absType, factory
contains
subroutine factory(t, switch)
class(absType), allocatable, intent(out) :: t
character(*), intent(in) :: switch
select case(switch)
case('A')
allocate(typeA :: t)
case('B')
allocate(typeB :: t)
end select
end subroutine
end module
并在测试程序中使用它:
program test
use factoryMod
implicit none
class(absType), allocatable :: foo
call factory(foo, 'A')
call foo%info() ! Output: i: 0 j: 1
call factory(foo, 'B')
call foo%info() ! Output: i: 0 k: 2.000000
end program
你可以按照自己的意愿制作这个。我在这里使用一个简单的字符串来选择要在factory
中分配的实际类型,但是我还使用了一个实现,我将连接的输入名称列表文件的iunit
传递给工厂。在这种情况下,工厂不仅可以使用此文件来确定要创建的类型,还可以执行进一步的特定于类型的设置,无论是在工厂本身还是在某种类型绑定的初始化例程中(使用相同的输入)文件)。
另请注意,此示例工厂是子例程而不是函数,因为Fortran 2003中不允许赋值foo = factory('A')
.F2008不再禁止它,但支持目前并不普遍。