SOU*_*ser 1 fortran types module interface
如下面的代码示例所示,person_list是一个用户派生类型,包含一个类型绑定过程compare_persons.我希望compare_persons能够接受某个组compareFunc作为其参数之一,因此声明接口部分compareFunc.注意第一个参数compareFunc是类型person_list.(正如您所说,person_list就像TStringList在Delphi的VCL中一样.)
编译无法进行.错误消息是:
[root@localhost new]# ifort -c lib1.f90
lib1.f90(26): error #6457: This derived type name has not been declared. [PERSON_LIST]
TYPE(person_list) :: persons ! error #6457: This derived type name has not been declared. [PERSON_LIST]
-------------------------^
lib1.f90(23): error #6404: This name does not have a type, and must have an explicit type. [PERSONS]
FUNCTION compareFunc(persons, index1, index2) ! error #6404: This name does not have a type, and must have an explicit type. [PERSONS]
-------------------------------------^
compilation aborted for lib1.f90 (code 1)
Run Code Online (Sandbox Code Playgroud)
错误消息似乎表明模块之间的循环引用?因此,我想知道如何为过程参数声明接口部分,而过程参数又引用同一模块的用户派生类型?任何见解将不胜感激!
PS:尝试这个模块的原因是OO编程风格的偏好.尝试fortran的原因是一个很大的代码库.
PS:编译器是英特尔Fortran编译器,版本如下:
[root@localhost new]# ifort --version
ifort (IFORT) 12.1.0 20111011
Copyright (C) 1985-2011 Intel Corporation. All rights reserved.
Run Code Online (Sandbox Code Playgroud)
MODULE lib1
TYPE person_list
CONTAINS
PROCEDURE, PASS :: compare_persons
END TYPE
CONTAINS
FUNCTION compare_persons(this, index1, index2, compareFunc)
IMPLICIT NONE
INTEGER :: compare_persons
CLASS(person_list) :: this
INTEGER, INTENT(IN) :: index1
INTEGER, INTENT(IN) :: index2
INTERFACE
FUNCTION compareFunc(persons, index1, index2) ! error #6404: This name does not have a type, and must have an explicit type. [PERSONS]
IMPLICIT NONE
INTEGER :: compareFunc
TYPE(person_list) :: persons ! error #6457: This derived type name has not been declared. [PERSON_LIST]
INTEGER :: index1
INTEGER :: index2
END FUNCTION compareFunc
END INTERFACE
compare_persons = compareFunc(this, index1, index2)
END FUNCTION compare_persons
END MODULE lib1
Run Code Online (Sandbox Code Playgroud)
tpg2114 找出解决方案!MODULE lib1
TYPE person_list
CONTAINS
PROCEDURE, PASS :: compare_persons
END TYPE
INTERFACE
FUNCTION CompareFuncInterface(persons, index1, index2)
IMPORT person_list
IMPLICIT NONE
INTEGER :: CompareFuncInterface
TYPE(person_list), INTENT(IN) :: persons
INTEGER, INTENT(IN) :: index1
INTEGER, INTENT(IN) :: index2
END FUNCTION CompareFuncInterface
END INTERFACE
CONTAINS
FUNCTION compare_persons(this, index1, index2, compareFunc)
IMPLICIT NONE
INTEGER :: compare_persons
CLASS(person_list), INTENT(IN) :: this
INTEGER, INTENT(IN) :: index1
INTEGER, INTENT(IN) :: index2
PROCEDURE (CompareFuncInterface) :: compareFunc
compare_persons = compareFunc(this, index1, index2)
END FUNCTION compare_persons
END MODULE lib1
Run Code Online (Sandbox Code Playgroud)
好的,我想通了:
MODULE lib1
TYPE :: persons
CONTAINS
PROCEDURE, PASS :: compare_persons
END TYPE persons
INTERFACE
INTEGER FUNCTION compareFunc_interface(personsIn, index1, index2)
IMPORT persons
IMPLICIT NONE
TYPE(persons), INTENT(IN) :: personsIn
INTEGER, INTENT(IN) :: index1
INTEGER, INTENT(IN) :: index2
END FUNCTION compareFunc_interface
END INTERFACE
CONTAINS
FUNCTION compare_persons(this, index1, index2, compareFunc)
IMPLICIT NONE
INTEGER :: compare_persons
CLASS(persons) :: this
INTEGER :: index1
INTEGER :: index2
PROCEDURE(compareFunc_interface) :: compareFunc
END FUNCTION compare_persons
END MODULE lib1
Run Code Online (Sandbox Code Playgroud)
根据2003标准,该IMPORT语句带来了从主机作用域单元到本地作用域单元的定义.如果您使用的是其他模块,则INTERFACE需要USE声明.但是,由于您是从较高的范围单元格导入,因此您需要使用IMPORT和列入您希望引入该范围的内容
编辑
另请注意,我添加PASS了类型绑定过程的声明.虽然不是必需的(因为这是默认操作),但我更喜欢总是放置PASS或者NOPASS意图始终是明确的.这有助于程序员(确保他们做他们认为他们正在做的事情)和任何阅读代码的人.