這是一個簡單的 Fortran95 代碼,GNU Fortran (gfortran) 可以很好地編譯:
Module Module1
Implicit None
Type MyType
Real(Kind=8) :: x, y
Integer :: n
End Type
Contains
Real(Kind=8) Function Calc(self)
Type(MyType) :: self
Calc = self%x**self%n self%y**self%n
End Function
End Module
Program Main
Use Module1
Implicit None
Type(MyType) :: A
A = MyType(3.0, 4.0, 2)
Write(*,*) Calc(A)
End Program Main
在這種情況下,A派生型別的物件在MyType內部創建和初始化Main。Calc()被呼叫并列印其結果。現在出現了一個稍微不同的代碼:
Module Module1
Implicit None
Type MyType
Real(Kind=8) :: x, y
Integer :: n
End Type
Type(MyType) :: A
Contains
Real(Kind=8) Function Calc(self)
Type(MyType) :: self
Calc = self%x**self%n self%y**self%n
End Function
End Module
Program Main
Use Module1
Implicit None
A = MyType(3.0, 4.0, 2)
Write(*,*) Calc(A)
End Program Main
相同的行數,相同的結果。但是這里被分配給內A的派生型別,并且只要該模塊被任何其他模塊匯入/使用()“旅行”,因此可以在后一個模塊中使用(當然,前提是之前已初始化)。與全域變數類似,但不完全一樣;不使用 Module1 的模塊無法訪問.MyTypeModule1UseAAA
問題是:這種編程“風格”是否存在概念問題?當然,A在其他模塊中所做的任何事情都必須小心,但這也適用于其他變數。
我可以看到使用這些“旅行”物件的一些優點,但我可能會遺漏一些東西。
uj5u.com熱心網友回復:
在您的第一個示例中,A是一個區域變數,但在您的第二個示例中,A是一個全域變數。全域變數通常是一個壞主意的原因有很多,在 Stack Overflow 1 2 3和 Stack Exchange 4的各個地方都有深入的解釋。
舉一個具體的例子,考慮以下代碼:
module module2
use module1
implicit none
contains
subroutine foo()
A = MyType(1.0, 2.0, 3)
write(*,*) calc(A)
end subroutine
end module
module module3
use module2
implicit none
contains
subroutine bar()
A = MyType(2.0, 3.0, 3)
call foo()
write(*,*) calc(A)
end subroutine
end module
program main
use module3
implicit none
call bar()
end program main
而不是列印
9.0
35.0
正如所料,這改為列印
9.0
9.0
由于任何更改A都必然是副作用,因此這類問題可能很難避免。另請注意,module3這不是顯式use module1的,而是隱式使用module1via use module2。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/461497.html
