说到操作,比如这里需要的比较操作,有两种不同的类型:内在操作和定义操作。
内在操作是编译器“默认知道”的操作,而定义的操作是由正在编译/使用的代码提供的操作。
仅对固有类型提供固有比较操作。对于内在一元运算符(例如一元减号-),操作数必须是内在类型;对于内在二元运算符,两个操作数都必须是内在类型。
即使对于相等和不等,定义的操作也必须用于派生类型。该问题的错误消息是说编译器不知道/无法访问此类定义的操作。其他编译器可能会给出诸如
之类的消息
错误 #6355:此二元运算对该数据类型无效。
或
.NE 的操作数。运算符属于派生类型
或
1511-026 (S) 操作数类型不允许用于比较运算。
由于没有可用的已定义操作,编译器只能将派生类型视为内在操作的操作数——这是不允许的。
为了提供一个定义好的操作,我们首先提供一个函数。这个函数返回一个真/假值是有意义的,它采用这个派生类型的两个操作数,而不是修改它们:
logical function datetime_unequal(lhs, rhs)
class(datetime), intent(in) :: lhs, rhs
datetime_unequal = ... ! Implement inequality test
end function datetime_unequal
我们可以以显而易见的方式使用这个函数(而不是作为运算符):
do while (datetime_unequal(session_cursor, session_end)))
...
end do
这对于许多目的可能就足够了,但是我们可以继续我们的方法来进行定义的比较操作。 (为了保持一致性,我们将调用我们的运算符/=。)我们通过提供泛型接口或泛型绑定重载operator(/=) 来做到这一点。
考虑
module datetime_mod
implicit none
type datetime
...
contains
procedure datetime_unequal
! A generic binding
generic :: operator(/=) => datetime_unequal
end type
! A generic interface
interface operator(/=)
module procedure datetime_unequal
end interface
contains
logical function datetime_unequal(lhs, rhs)
class(datetime), intent(in) :: lhs, rhs
datetime_unequal = ... ! Implement inequality test
end function datetime_unequal
end module datetime_mod
请注意,您不需要同时提供泛型接口和泛型绑定。实际上,在大多数情况下,泛型绑定(在类型定义中定义)更可取:只要类型定义本身可访问,它就可以访问;通用接口具有独立的可访问性。
还要注意,比较函数的参数是多态的 (class(datetime)) 以允许将其用作类型绑定过程。使用独立功能,这不是必需的。
最后,这个讨论的大部分内容适用于更一般的(二进制)操作,而不仅仅是那些重载内在操作的操作。