内部多态分配是某些Fortran编译器(例如ifort 18,nagfor 6.2)的最新功能,而旧版本(例如ifort 17,gfortran 6.3)不可用。适用于这些较旧版本的一种著名解决方案是使用定义的赋值,如以下示例所示(摘自Chivers and Sleightholme):
DATETIME
此示例可与ifort 15.0.3和gfortran 6.3.0一起编译并很好地工作。但是使用nagfor 6.2时,在编译过程中(对于行datetime
)出现以下错误:
from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import file
SCOPES = ['https://www.googleapis.com/auth/drive.readonly']
def login_gdrive(SCOPES):
store = file.Storage('../personal_token.json')
creds = store.get()
return build('drive', 'v3', http=creds.authorize(Http()))
def gdrive_download(file_id):
request = drive_service.files().get(fileId=file_id)
result = request.execute()
#will return metadata of file but I will only get file name
file_name = result['name']
print(f"File name is {file_name}")
#will get actual file
request = drive_service.files().get_media(fileId=file_id)
result = request.execute()
print("Downloading " + file_name)
#will write file using the file_name
with open(file_name, mode="wb") as f:
f.write(result)
print("Finished writing " + file_name)
drive_service = login_gdrive(SCOPES)
gdrive_download('1oiD6h-ixAUTIWebEdN-jV8MO0sssoQTI')
out... File name is sample_data_2018-10-21.csv
out... Downloading sample_data_2018-10-21.csv
out... Finished writing sample_data2018-10-21.csv
对于我尚不清楚,为什么这两个编译器不是要分配的多态变量,为什么要尝试在指令module deftypes
type, abstract :: shape_t
integer :: x = 0, y = 0
end type shape_t
type, extends(shape_t) :: circle_t
integer :: radius = 0
end type circle_t
interface assignment(=)
module procedure generic_shape_assign
end interface
contains
subroutine generic_shape_assign ( lhs, rhs )
class(shape_t), intent(in ) :: rhs
class(shape_t), allocatable, intent(out) :: lhs
print*,' --> in generic_shape_assign'
allocate(lhs, source = rhs)
end subroutine generic_shape_assign
end module deftypes
program check_assign
use deftypes
implicit none
class(shape_t), allocatable :: myshape
type (circle_t) :: mycirc1, mycirc2
mycirc1 = circle_t ( 1, 2, 3 )
print*,'A polymorphic assignment: myshape = mycirc1'
myshape = mycirc1
print*,'An intrinsic assignment: mycirc2 = mycirc1'
mycirc2 = mycirc1
end program check_assign
中使用定义的赋值。
当然,如果删除定义的赋值,它适用于nagfor,但不适用于其他旧编译器。您知道此错误来自何处以及如何解决吗?
答案 0 :(得分:3)
我认为编译器拒绝该程序是正确的。但是,如果您与NAG签订了支持合同,我强烈建议您让他们将我的评论视为权威。
我将展示我的推理。
很明显,对特定过程generic_shape_assign
的引用类似于
type(circle_t) mycirc1, mycirc2
call generic_shape_assign(mycirc2, mycirc1)
无效。它失败是因为实际参数mycirc2
与可分配的多态伪参数lhs
相对应:
您引用的错误消息包含由于违反此秒而导致程序被拒绝。
因此,这意味着generic_shape_assign
不是通用规范assignment(=)
的有效特定过程(仅供参考),对吗?因此,没有选择定义的分配,编译器应该退回到固有分配吗?
这是事情变暗的地方(至少对我来说是这样)。
我认为为定义的分配选择了特定的子例程generic_shape_assign
,因此编译器正确地拒绝了您的程序,因为您没有正确地调用此特定的子例程。
让我们进一步使用Fortran 2008 7.2.1.4,其中定义了赋值语句何时是已定义的赋值语句。
要确定子例程generic_shape_assign
是否定义了已定义的赋值语句mycirc2=mycirc1
,我们看一下给定的点:
generic_shape_assign
是具有两个伪参数(此处为lhs
和rhs
)的子例程; generic_shape_assign
提供了通用规范assignment(=)
; lhs
(类型为shape_t
)与mycirc2
类型兼容(动态类型为circle_t
); rhs
类似; 我们满足了作为已定义分配的所有要求:没有要求指出已定义分配要求所选子例程是可调用的!
总结:
我不清楚,为什么这两个编译器不是可分配的多态变量,为什么编译器会尝试在指令
mycirc2 = mycirc1
中使用已定义的赋值。
因为使用定义的分配与左手边和右手边是多态的还是可分配的无关。
最后,我认为无论我的推理是正确还是不正确,编译器的诊断消息都可以得到改善。