Fortran 将过程保存为派生类型中的 属性

Fortran save procedure as property in derived type

是否可以将过程存储为派生类型的 属性?我在想一些类似的事情:

  module funcs_mod
  public :: add
  contains
  function add(y,z) result (x)
    integer,intent(in) :: y,z
    integer :: x
    x = y + z
  end function
  end module

  module type_A_mod
  use funcs_mod
  public :: type_A,set_operator
  type type_A
    procedure(),pointer,nopass :: operator
  end type
  contains
  subroutine set_operator(A,operator)
    external :: operator
    type(type_A),intent(inout) :: A
    A%operator => operator
  end subroutine
  function operate(A,y,z) result(x)
    type(type_A),intent(in) :: A
    integer,intent(in) :: y,z
    integer :: x
    x = A%operator(y,z)
  end function
  end module

  program test
  use type_A_mod
  use funcs_mod
  type(type_A) :: A
  call set_operator(A,add)
  write(*,*) operate(A,1,2)
  end program

但这并没有成功编译。显示了几个错误,包括:

1) 过程指针组件中的语法错误

2) (1) 处的 'operator' 不是 'type_a' 结构的成员

以及一些不成功的使用语句。有没有办法正确地做到这一点?非常感谢任何帮助。

更新:

我已经将 procedure,pointer 修改为 procedure(),pointer,现在错误是

1) FUNCTION 属性与 'operator'

中的 SUBROUTINE 属性冲突

2) 无法将 UNKNOWN 转换为 INTEGER(4)

均指x = A%operator(y,z)

如您所见,声明过程指针声明的语法需要 procedure([interface]), pointer [, ...] :: ...。您选择了 procedure(), pointer, nopass :: operator.

procedure() 的结果是您没有声明 operator 是函数还是子例程。这并没有什么不妥,但是还有更多的工作要做,就是要让编译器相信您正在一致地使用这些引用。你的编译器似乎不相信你。

我不会详细说明编译器认为您的意思,而是采用不同的方法。

您引用 A%operator 类型的结构 A,该组件作为函数 operate 的结果。你在声明后一个函数时说得很清楚,它的结果是一个整数。

现在,假设您不想通过 type/kind 转换来获得该整数结果来做令人兴奋的事情,我们将假设您始终希望 A%operator 成为一个函数与整数结果。这意味着您可以将该过程指针组件声明为具有整数结果的函数。

这仍然留给你选择:

type type_A
  procedure(integer),pointer,nopass :: operator
end type

是一个具有整数结果和隐式接口的函数,并且

type type_A
  procedure(add),pointer,nopass :: operator
end type

是一个具有与函数add匹配的显式接口的函数。

您正在进行的设计选择会影响您的最终决定。

最后一点,您没有使用 implicit none。当我们考虑您的线路时,这很重要

external :: operator

如果 operator 是一个函数,那么(根据隐式类型规则)它有一个(默认)真实结果。因此,您想更改为以下之一

integer, external :: operator

procedure(integer) :: operator

procedure(add) :: operator

总而言之,并附和 Vladimir F 的评论,请仔细考虑您的设计。您当前有来自 operate 的引用(在函数结果及其参数中)的约束,看起来您确实知道该组件将具有特定的接口。如果您确定,请使用 procedure(add) 作为声明/