データ参照とフィールドシンボルは非常によく似ており、よく似た方法で使用されますが(他の回答を参照)、根本的に異なります。
データ参照は、文字列や整数のように、値を格納する変数です。それらはメモリとコンテンツの固定サイズを持っています。唯一の違いは、これらの参照が他のデータオブジェクトへのポインタであるということです。つまり、コンテンツには特別な意味があります。それらはどこも指すことができず、逆参照することができ、他のルーチンに渡すことができ、ポインター(GET REFERENCE
)またはそれが指す値のいずれかを操作することができます。特別なことは何もありません。実際には、お気に入りのプログラミング言語から知っているポインタだけです。
フィールドシンボルは「実際の」変数ではありません。ドキュメントには次のように記載されています
フィールド用のスペースを物理的に予約しません
フィールドシンボルは、実際にはABAPVMのローカルシンボルテーブルの巧妙な操作にすぎません。これを説明しようと思います-これは非常に単純化されたモデルであることに注意してください。3つの変数を宣言するとします。
DATA: my_char TYPE c,
my_int TYPE i,
my_ref TYPE REF TO i.
次に、シンボルテーブルには、特に次のようなエントリが含まれます。
name type size addr
------------------------------
MY_CHAR c 1 0x123456
MY_INT i 4 0x123457
MY_REF r ? 0x123461
(参照変数の実際のサイズについてはわかりません。)
これらのエントリは、値を含むアドレスのみを指します。これらの変数の範囲によっては、まったく異なるメモリ領域に存在する可能性がありますが、現時点ではそれは問題ではありません。重要なポイントは次のとおりです。
- 変数用にメモリを予約する必要があります(これは、参照用であっても自動的に行われます)。
- 参照は、他のすべての変数と同じように機能します。
これにフィールドシンボルを追加しましょう:
FIELD-SYMBOLS: <my_fs> TYPE any.
その場合、シンボルは次のようになります。
name type size addr target
--------------------------------------
MY_CHAR c 1 0x123456
MY_INT i 4 0x123457
MY_REF r ? 0x123461
<MY_FS> *
フィールドシンボルは、初期状態(未割り当て)で作成されます。どこも指していません。この状態で使用すると、短いダンプが発生します。重要な点は、他の変数のように「ヒープ」メモリに支えられていないということです。しましょう
ASSIGN my_char TO <my_fs>.
この場合も、シンボルは次のようになります。
name type size addr target
--------------------------------------
MY_CHAR c 1 0x123456
MY_INT i 4 0x123457
MY_REF r ? 0x123461
<MY_FS> * MY_CHAR
これで、にアクセスする<my_fs>
と、ランタイムシステムはそれをフィールドシンボルとして認識し、シンボルテーブルで現在のターゲットを検索し、すべての操作をの実際の場所にリダイレクトしますmy_char
。一方、コマンドを発行する場合
GET REFERENCE OF my_int INTO my_ref.
シンボルテーブルは変更されませんが、「ヒープアドレス」0x123461に「アドレス」0x123457があります。my_char = 'X'
またはのような値の割り当てmy_int = 42 * 2
。
これは、非常に単純化されたバージョンでは、変更パラメーターとしてフィールドシンボルを渡し、サブルーチン内でそれらを再割り当てできるようにすることができない理由です。それらは他の変数と同じようには存在せず、それらが追加されたシンボルテーブルの範囲外では意味がありません。