在子例程调用中使用用户定义的派生类型分配
Using user-defined derived type assignments in subroutine calls
我想通过编写更像 pythonic 的字符串类型来克服 fortran 中糟糕且不直观的字符串处理,但我偶然发现了派生类型(重载)赋值的一个平均问题。
主要类型应该像
TYPE t_string
CHARACTER(:), ALLOCATABLE :: str
contains
...
END TYPE t_string
它在派生类程序中的威力。当然,新的字符串类型应该尽可能与固有的 CHARACTER(len=*)
类型没有区别。特别是我想使用内部例程(使用 character
类型)而不进行任何额外的类型转换。因此,我在 CLASS(t_string)
和 CHARACTER(len=*)
之间定义了一个赋值运算符。例如。 open
使用新类型创建文件应该如下所示:
type(t_string) :: filename
filename = '...'
open(file = filename, ...)
! ^ assignment here
由于t_string
和CHARACTER(len=*)
之间存在赋值file=filename
,因此调用open
应该没有问题。但是由于类型不匹配,我得到了一个错误。
我想问题是,子例程调用中的赋值并不是真正的赋值,而只是一些语法约定。
- 有什么解决办法吗?
- “子程序分配”不是真正的分配的原因是什么(在 fortran 语言的设计方面)?
- 我不想打电话
open(file = filename%str, ...)
这是一个mwe:
MODULE m_string
IMPLICIT NONE
SAVE
INTERFACE ASSIGNMENT(=)
MODULE PROCEDURE :: string_operator_equal_s, string_operator_equal_c
END INTERFACE ASSIGNMENT(=)
TYPE t_string
CHARACTER(:), ALLOCATABLE :: str
END TYPE t_string
CONTAINS
ELEMENTAL SUBROUTINE string_operator_equal_s(lhs,rhs)
IMPLICIT NONE
CLASS(t_string), INTENT(inout) :: lhs
CLASS(t_string), INTENT(in) :: rhs
lhs%str = rhs%str
END SUBROUTINE string_operator_equal_s
ELEMENTAL SUBROUTINE string_operator_equal_c(lhs,rhs)
IMPLICIT NONE
CLASS(t_string), INTENT(inout) :: lhs
CHARACTER(len=*), INTENT(in) :: rhs
lhs%str = rhs
END SUBROUTINE string_operator_equal_c
SUBROUTINE routine(char)
CHARACTER(len=*) :: char
END SUBROUTINE routine
END MODULE m_string
PROGRAM test
USE m_string
TYPE(t_string) :: str
CHARACTER(len=10) :: char
CALL routine(char) ! no error
CALL routine(char=str) ! error: #6633: The type of the actual argument differs from the type of the dummy argument. [STR]
END PROGRAM test
Since there is an assignment file=filename between t_string and CHARACTER(len=*) there should be no problem in the call to open.
不存在此类分配。您仅使用说明符名称来指定要传递的语句的哪个参数(类似于 Python 中的 keyword/named 参数,但不相同)。 open
实际上不是一个过程,它是一个语句,但它也有它的“参数”(说明符)以它们的名字来区分。
因此,不得调用派生赋值。您必须自己转换为 character
。
我想通过编写更像 pythonic 的字符串类型来克服 fortran 中糟糕且不直观的字符串处理,但我偶然发现了派生类型(重载)赋值的一个平均问题。 主要类型应该像
TYPE t_string
CHARACTER(:), ALLOCATABLE :: str
contains
...
END TYPE t_string
它在派生类程序中的威力。当然,新的字符串类型应该尽可能与固有的 CHARACTER(len=*)
类型没有区别。特别是我想使用内部例程(使用 character
类型)而不进行任何额外的类型转换。因此,我在 CLASS(t_string)
和 CHARACTER(len=*)
之间定义了一个赋值运算符。例如。 open
使用新类型创建文件应该如下所示:
type(t_string) :: filename
filename = '...'
open(file = filename, ...)
! ^ assignment here
由于t_string
和CHARACTER(len=*)
之间存在赋值file=filename
,因此调用open
应该没有问题。但是由于类型不匹配,我得到了一个错误。
我想问题是,子例程调用中的赋值并不是真正的赋值,而只是一些语法约定。
- 有什么解决办法吗?
- “子程序分配”不是真正的分配的原因是什么(在 fortran 语言的设计方面)?
- 我不想打电话
open(file = filename%str, ...)
这是一个mwe:
MODULE m_string
IMPLICIT NONE
SAVE
INTERFACE ASSIGNMENT(=)
MODULE PROCEDURE :: string_operator_equal_s, string_operator_equal_c
END INTERFACE ASSIGNMENT(=)
TYPE t_string
CHARACTER(:), ALLOCATABLE :: str
END TYPE t_string
CONTAINS
ELEMENTAL SUBROUTINE string_operator_equal_s(lhs,rhs)
IMPLICIT NONE
CLASS(t_string), INTENT(inout) :: lhs
CLASS(t_string), INTENT(in) :: rhs
lhs%str = rhs%str
END SUBROUTINE string_operator_equal_s
ELEMENTAL SUBROUTINE string_operator_equal_c(lhs,rhs)
IMPLICIT NONE
CLASS(t_string), INTENT(inout) :: lhs
CHARACTER(len=*), INTENT(in) :: rhs
lhs%str = rhs
END SUBROUTINE string_operator_equal_c
SUBROUTINE routine(char)
CHARACTER(len=*) :: char
END SUBROUTINE routine
END MODULE m_string
PROGRAM test
USE m_string
TYPE(t_string) :: str
CHARACTER(len=10) :: char
CALL routine(char) ! no error
CALL routine(char=str) ! error: #6633: The type of the actual argument differs from the type of the dummy argument. [STR]
END PROGRAM test
Since there is an assignment file=filename between t_string and CHARACTER(len=*) there should be no problem in the call to open.
不存在此类分配。您仅使用说明符名称来指定要传递的语句的哪个参数(类似于 Python 中的 keyword/named 参数,但不相同)。 open
实际上不是一个过程,它是一个语句,但它也有它的“参数”(说明符)以它们的名字来区分。
因此,不得调用派生赋值。您必须自己转换为 character
。