如何修改该程序以提高其性能和内存效率,而又不会造成不必要的阅读和维护困难?
同时实现这三个目标几乎总是困难的,有时甚至是根本不可能的。除非您有特殊原因不这样做,否则我建议您首先专注于使代码易于阅读和维护,然后才尝试提高其性能和内存效率。后一步只能在分析代码以查看哪些位实际需要优化之后才进行。
考虑到这一点,让我们看看是否可以稍微简化您的代码。既然您已经有了多种类型,那么让我们完全面向对象,并引入一些多态性。
如果我们继承Rabbit
from Animal
,我们可以避免存储animal_type
字段,而是使用类型绑定过程生成它,例如
module animal_mod
implicit none
! Define the base Animal type.
type, abstract :: Animal
integer :: age
contains
procedure(animal_type_Animal), deferred, nopass :: animal_type
end type
! Define the interface for the `animal_type` functions.
interface
function animal_type_Animal() result(output)
character(256) :: output
end function
end interface
end animal_mod
and
module rabbit_mod
use animal_mod
implicit none
! Define the `Rabbit` type as an extension of the `Animal` type.
! Note that `Rabbit` has an `age` because it is an `Animal`.
type, extends(Animal) :: Rabbit
integer :: estimated_carrots_eaten
contains
procedure, nopass :: animal_type => animal_type_Rabbit
end type
contains
! Define the implementation of `animal_type` for the `Rabbit` type.
function animal_type_Rabbit() result(output)
character(256) :: output
output = "rabbit"
end function
end module
现在我们希望能够创建一系列动物。 Fortran 不允许多态数组,因此我们需要定义一个包含动物并且可以制成数组的类型。就像是
module animal_box_mod
use animal_mod
implicit none
type :: AnimalBox
class(Animal), allocatable :: a
end type
end module
我们现在可以创建一系列动物,例如
type(AnimalBox) :: animals(3)
animals(1)%a = Rabbit(age=3, estimated_carrots_eaten=0)
animals(2)%a = Frog(age=3, estimated_bugs_eaten=4, length=1.7786)
animals(3)%a = Mouse(age=4, estimated_cheese_eaten=7, coat="Yellow")
而不是使用类似的方法feed_rabbit(7)
,您可以改用类型绑定方法。如果我们将其添加为
module rabbit_module
type, extends(Animal) :: Rabbit
... ! as above
contains
... ! as above
procedure :: feed
end type
contains
... ! as above
subroutine feed(this)
class(Rabbit), intent(inout) :: this
this%estimated_carrots_eaten = this%estimated_carrots_eaten + 1
end subroutine
end module
然后我们可以使用我们的animals
数组为
select type(a => animals(1)%a); type is(Rabbit)
a.feed()
end select