我尝试向this module添加一个由@VladimirF编写的过程,该过程在Fortran 2003中实现了一个通用的链表。为了方便起见,我想能够将列表的内容输出为数组,所以我将以下过程添加到名为lists.f90
的文件中的列表模块中:
subroutine list_as_array(self, arrayOut)
class(list),intent(inout) :: self
class(*),dimension(1:self%length),intent(out) :: arrayOut
integer :: i
type(list_node), pointer :: nodeIter
nodeIter = self%first
do i = 1,self%length
arrayOut(i) = nodeIter%item ! <---ERROR here
if (i<self%length) then
nodeIter = nodeIter%next
end if
end do
end subroutine list_as_array
ifort 18.0.0
出现以下错误:
lists.f90(324): error #8304: In an intrinsic assignment statement, variable shall not be a non-allocatable polymorphic. [ARRAYOUT]
arrayOut(i) = nodeIter%item
------^
我是F2003 +中的多态的新手,所以我不理解错误信息或其上下文。怎么了,怎么修好?
答案 0 :(得分:2)
错误消息表示它所说的内容。描述内在赋值语句的Fortran 2008标准说:&#34;如果变量是多态的,它应该是可分配的而不是一个共同的&#34; arrayOut是CLASS(*)
,它具有多态性。只能分配可分配的多态性。
至于&#34;如何修复它&#34;,这需要更多的背景。
答案 1 :(得分:2)
首先,关于错误消息。在没有一些已定义的赋值的情况下,语句
arrayOut(i) = nodeIter%item
是一个内在的赋值语句。
Fortran 2008(不是Fortran 2003)允许此语句左侧的变量具有多态性。 arrayOut(i)
这里是(无限制的)多态。但是,在允许赋值给多态变量时存在限制(F2008,7.2.1.1(1)):
如果变量是多态的,那么它应该是可分配的而不是一个共同的
在这种情况下,编译器抱怨,因为arrayOut(i)
不可分配。但是,即使使arrayOut
可分配也无济于事:arrayOut(i)
是数组的一个元素,永远不会被分配。
你想在这里做什么,不能做。这一点应该清楚,因为在分配数组元素时,您并不能保证数组的每个元素都与其他元素完全相同。这是Fortran数组的要求,甚至是多态数组。
关于如何做你想做的事,有几种方法:
后者,如
type stuff
class(*), allocatable :: item
end type stuff
type(stuff) arrayOut(length)
在问题的其他背景下出现并在这里回答。
对于“令人信服”,你需要使左侧非多态。
答案 2 :(得分:2)
我认为其他答案很好地描述了这个问题。无法分配多态非可分配变量。并且数组元素永远不可分配。
我已经考虑过如何做这样的事情,但是我没有想出一个令人满意的解决方案如何在库中创建这样的函数。主要问题是没有类型保护只会检查两个实体的动态类型是否相同。您必须在SELECT TYPE中指定实际类型。
作为图书馆的用户,一旦您知道所有元素属于同一类型,您就有两种可能性
使用同一个库中的参数列表
为可出现在数组中的每种类型创建自己的函数。不是在库中,而是在您自己的代码中。您必须承诺所有元素都属于该类型。
subroutine integer_list_as_array(self, arrayOut)
class(list),intent(inout) :: self
integer,dimension(1:self%length),intent(out) :: arrayOut
...
end subroutine integer_list_as_array
如果有人知道这样做的伎俩,只是假设所有元素属于同一类型,但没有指定类型,我想知道。