lotsの変数、関数、サブルーチンを含むFortran 90モジュールがあるとします。 USE
ステートメントで、次の規則に従います。
, only :
などのUSE [module_name], only : variable1, variable2, ...
構文を使用して、使用している変数/関数/サブルーチンを明示的に宣言しますか?USE [module_name]
?一方で、only
句はコードをもう少し冗長にします。ただし、コード内で自分自身を繰り返す必要があり、モジュールにlotsの変数/関数/サブルーチンが含まれていると、物事が見苦しくなり始めます。
次に例を示します。
module constants
implicit none
real, parameter :: PI=3.14
real, parameter :: E=2.71828183
integer, parameter :: answer=42
real, parameter :: earthRadiusMeters=6.38e6
end module constants
program test
! Option #1: blanket "use constants"
! use constants
! Option #2: Specify EACH variable you wish to use.
use constants, only : PI,E,answer,earthRadiusMeters
implicit none
write(6,*) "Hello world. Here are some constants:"
write(6,*) PI, &
E, &
answer, &
earthRadiusInMeters
end program test
Update誰かが "Fortran?C#でコーディングし直せ!"投票してください。
更新
Tim Whitcombの答え が好きです。FortranのUSE modulename
とPythonのfrom modulename import *
を比較します。以前にStack Overflowにあったトピック:
「モジュールのインポート」または「モジュールのインポートから」
「from module import *」を使用しないでください。妥当な大規模なコードセットの場合、「*インポート」すると、モジュールにセメントで固定され、削除できなくなります。これは、コードで使用されているアイテムが「モジュール」からのものであるかどうかを判断するのが難しく、インポートをもう使用しないと思うポイントに到達するのが東になっているためです。
python imports? の良い経験則は何ですか?)==
x import *からしないでください-メソッドがどこから来たのか簡単に見ることができないため、コードを理解するのが非常に難しくなります(x import *; from y import *; my_func()-my_funcはどこで定義されていますか?)
だから、私はモジュールで使用しているすべてのアイテムを明示的に述べることのコンセンサスに傾いています
USE modulename, only : var1, var2, ...
そして ステファノボリーニが言及 のように、
[もし]モジュールが大きすぎて追加のみを強いられている場合、それはモジュールが大きすぎることを意味します。それを分割します。
それはバランスの問題です。
モジュールからいくつかのものだけを使用する場合は、使用しているものを明確に指定するために、ONLYを追加すれば意味があります。
モジュールから多くのものを使用する場合、ONLYを指定すると多くのものが続くため、あまり意味がありません。あなたは基本的にあなたが使用するものをピッキングしていますが、本当の事実はあなたがそのモジュール全体に依存しているということです。
ただし、最終的には、これが最良の哲学です。名前空間の汚染を心配していて、追加する必要があるほど大きなモジュールがある場合は、モジュールが大きすぎることを意味します。それを分割します。
更新:Fortran? python;)でコーディングし直すだけです
以前はuse modulename
を実行していました-その後、アプリケーションが成長するにつれて、関数のソースを見つけるのがますます難しくなりました(grepを使用せずに)ファイルごとに1つのサブルーチンがあります。これには独自の問題がありますが、テキストエディターを使用してコード内を移動し、必要なものをすばやく追跡することがはるかに簡単になります。
これを経験した後、可能な限りuse
...only
を使用するようになりました。また、Pythonの取得を開始し、from modulename import *
と同じ方法で表示します。モジュールが提供する素晴らしい機能はたくさんありますが、私はグローバルな名前空間を厳しく管理したいのです。
ここでの質問に正確に答えているわけではなく、何らかの理由でモジュールを分割して名前空間の衝突を開始したくない場合は、いくつかの状況で有用であることがわかった別のソリューションを投げます。派生型を使用して、1つのモジュールに複数の名前空間を格納できます。
変数の論理的なグループ化がある場合、各グループに独自の派生型を作成し、この型のインスタンスをモジュールに保存して、必要なグループのみをインポートできます。
小さな例:多くのデータがあり、その一部はユーザー入力であり、その他のデータはさまざまな初期化の結果です。
module basicdata
implicit none
! First the data types...
type input_data
integer :: a, b
end type input_data
type init_data
integer :: b, c
end type init_data
! ... then declare the data
type(input_data) :: input
type(init_data) :: init
end module basicdata
サブルーチンがinit
からのデータのみを使用する場合、それだけをインポートします:
subroutine doesstuff
use basicdata, only : init
...
q = init%b
end subroutine doesstuff
これは間違いなく普遍的に適用可能なソリューションではありません。派生型構文から余分な冗長性を得ることができます。そして、モジュールが上記のbasicdata
ソートではなく、むしろallthestuffivebeenmeaningtosortout
variety。とにかく、この方法で脳に簡単に収まるコードを手に入れることができました。
USEの主な利点は、私だけが、必要のないものでグローバルネームスペースを汚染しないことです。
はい、use module, only: ...
を使用してください。複数のプログラマーがいる大規模なコードベースの場合、誰でも簡単にコードをフォローできます(またはgrep
を使用します)。
インクルードを使用しないでください。代わりに小さなモジュールを使用してください。 includeは、useモジュールと同じレベルでコンパイラーによってチェックされないソースコードのテキスト挿入です。 FORTRAN:INCLUDEとモジュールの違い を参照してください。 Include
は一般に、人間とコンピューターの両方がコードを使用することを難しくします。つまり、使用すべきではありません。例from mpi-forum:「mpif.hインクルードファイルの使用は強く推奨されておらず、MPIの将来のバージョンでは非推奨になる可能性があります。」 ( http://mpi-forum.org/docs/mpi-3.1/mpi31-report/node411.htm )。
以前に与えられたほとんどの答えに同意し、_use ..., only: ...
_が進むべき道であり、意味がある場合は型を使用し、可能な限り python thinking を適用します。別の提案は、インポートされたモジュールでprivate
/public
ステートメントとともに適切な命名規則を使用することです。
たとえば、netcdf
ライブラリーは_nf90_<some name>
_を使用します。これは、インポート側での名前空間の汚染を制限します。
_use netcdf ! imported names are prefixed with "nf90_"
nf90_open(...)
nf90_create(...)
nf90_get_var(...)
nf90_close(...)
_
同様に、このライブラリの ncio ラッパーは_nc_<some name>
_(_nc_read
_、_nc_write
_...)を使用します。
重要なのは、_use: ..., only: ...
_の関連性が低くなるような設計では、ヘッダーに適切なprivate
/public
属性を設定することにより、インポートされたモジュールの名前空間を制御することです。読者がどのレベルの「汚染」に直面しているかを評価するには、それを簡単に調べるだけで十分です。これは基本的に_use ..., only: ...
_と同じですが、インポートされたモジュール側にあります-したがって、インポートごとにではなく、一度だけ書き込まれます)。
もう1つ:オブジェクト指向とpythonに関する限り、私の見解の違いは、Fortranは比較的新しい標準であるため、タイプバインドされたプロシージャを実際に奨励していないということです(たとえば、いくつかのツールと互換性がなく、合理的ではないが、それは異常なことです)、また、プロシージャフリーの派生型コピー(type(mytype) :: t1, t2
および_t2 = t1
_)などの便利な動作を壊します。これは、クラスだけでなく、タイプとすべてのタイプバインドプロシージャをインポートする必要があることを意味します。これだけでも、Fortranコードはpythonよりも冗長になり、プレフィックスの命名規則などの実用的なソリューションが役立ちます。
IMO、一番下の行は、Pythonで教えられているように、それを読む人(これには後の自分を含む)のコーディングスタイルを選択することです。最良の方法は、各インポートでより詳細な_use ..., only: ...
_ですが、場合によっては、単純な命名規則がそれを行います(十分な規律があれば...)。
私はパーティーに少し遅れていることを知っていますが、定数と必ずしも計算された値のセットの後だけであれば、Cのようにしてインクルードファイルを作成できます:
ファイル内、例えばconstants.for
real, parameter :: pi = 3.14
real, parameter :: g = 6.67384e-11
...
program main
use module1, only : func1, subroutine1, func2
implicit none
include 'constants.for'
...
end program main
「real(4)」を削除するように編集され、一部の人は悪い習慣だと考えています。