我的问题是,可以使用选择类型块来区分 real :: realInput 从 real :: realArrayInput(:)?很明显, select type 可以用来区分派生类型,但是对于我如何(或者是否)它可能用于内在类型)变得不太清楚。
在Mad Libs表格中,可以在下面填入空格以区分上面的输入: <$ p $ 类型是(真实的) print *,我抓到了realInput类型是(___________) print * ,我抓到了realArrayInput end select
我发现了一些相关的帖子,并没有包含我希望得到的答案:
选择类型问题
确定变量类型
解决方案input 或者声明为数组或标量,即使它是多态的(甚至当它是无限多态时)。 最近与C TS(可能是F201X的一部分)的进一步互操作性引入了假定等级和RANK内在的概念,它可以做你想做的事情。但是,对于假设的排名对象可以做些什么有很多限制。不管那个SELECT TYPE仍然只能用于类型。
显然取决于你真正想要做什么(?)。 )......除了其他人提到的通用接口之外,在当前Fortran中有一个可以是数组或标量的对象的方法(还有其他可能性)是使用派生类型包装器,它是普通父类型的扩展。然后使用一个声明为父类型的多态对象(或者可以使用无限多态对象)来引用相关派生类型的对象。
TYPE :: parent END TYPE父 $ b $ TYPE,EXTENDS(父):: scalar_wrapper REAL :: scalar_component END TYPE scalar_wrapper TYPE,EXTENDS(父):: array_wrapper REAL :: array_component(10) END TYPE array_wrapper ... SUBROUTINE what_am_i(object)!请注意,该对象是标量,但不会告诉我们!动态类型对象的组件的等级。 CLASS(parent),INTENT(IN):: object !**** SELECT TYPE(object) TYPE IS(scalar_wrapper) PRINT( '我是一个有价值的标量',G0),& object%scalar_component TYPE IS(array_wrapper) PRINT('我是一个数组',*(G0,:,',')),& object%array_component CLASS DEFAULT PRINT('我不知道我在说什么') END SELECT END SUBROUTINE what_am_i
My question is, "Can a select type block be used to distinguish real :: realInput from real :: realArrayInput(:)?" It's clear how select type may be used to distinguish derived types, but becomes less clear to me how (or whether) it may be used on intrinsic types.
In Mad Libs form, can the blanks be filled in below to distinguish between the inputs above:
select type (input) type is (real) print *, "I caught the realInput" type is (___________) print *, "I caught the realArrayInput" end selectI've found some related posts that did not quite contain the answer I was hoping for:
Select Type Issues
Determining Variable Type
解决方案No. input is either declared as an array or a scalar, even when it is polymorphic (and even when it is unlimited polymorphic).
The recent further interoperability with C TS (which may be part of F201X) introduced the concept of assumed rank and the RANK intrinsic, which may do what you want. But there are many limitations around what can be done with assumed rank objects. And regardless of that SELECT TYPE still only works on type. The syntax of the select type construct simply doesn't permit specification of rank in the type guard statements.
Obviously depending on what it is that you actually want to do (?) ... and beyond generic interfaces mentioned by others, a way to have objects that can be either array or scalar in current Fortran (there are other possibilities) is to use derived type wrappers that are an extension of a common parent type. You then use a polymorphic object declared as the parent type (or you can use an unlimited polymorphic object) to refer to an object of the relevant derived type.
TYPE :: parent END TYPE parent TYPE, EXTENDS(parent) :: scalar_wrapper REAL :: scalar_component END TYPE scalar_wrapper TYPE, EXTENDS(parent) :: array_wrapper REAL :: array_component(10) END TYPE array_wrapper ... SUBROUTINE what_am_i(object) ! Note that object is scalar, but that doesn't tell us ! the rank of the components of the dynamic type of object. CLASS(parent), INTENT(IN) :: object !**** SELECT TYPE (object) TYPE IS (scalar_wrapper) PRINT "('I am a scalar with value ',G0)", & object%scalar_component TYPE IS (array_wrapper) PRINT "('I am an array with values ',*(G0,:,','))", & object%array_component CLASS DEFAULT PRINT "('I am not sure what I am.')" END SELECT END SUBROUTINE what_am_i