2017-01-11 9 views
8

Я хочу написать метод, который экспортирует таблицу ссылок. Это необходимо, потому что каждая его строка может иметь свою собственную структуру. Поэтому я объявляю типа, как это:Странное поведение при изменении строки таблицы по ссылке

... TYPE STANDARD TABLE OF REF TO data. 

Я думал, что это будет отличная идея, если бы я мог сразу изменить Таблицы последней строку вместо того, чтобы иметь отдельную рабочую область только для добавления.


Почему эта работа ...

FIELD-SYMBOLS: <lfs_struct> TYPE REF TO DATA. 
" ...  
APPEND INITIAL LINE TO ei_lines ASSIGNING <lfs_struct>. 
CREATE DATA <lfs_struct> TYPE (<lfs_field>-segnam). 
ASSIGN <lfs_struct>->* TO <lfs_target>. 

... но это не делает?

DATA: lo_struct TYPE REF TO data. 
" ...  
APPEND INITIAL LINE TO ei_lines REFERENCE INTO lo_struct. 
CREATE DATA lo_struct TYPE (<lfs_field>-segnam). 
ASSIGN lo_struct->* TO <lfs_target>. 

С «работой» Я имею в виду, что значение приложенной строки действительно меняется. Если я присвою что-то <lfs_target>, как и во втором примере, оно изменяется в самой структуре - но не внутри таблицы.

По-видимому, я изменяю ссылку в последнем примере. Но почему это работает с Field-Symbols?

ответ

5

Причина, по которой ваш код работает с символом поля, но не является объектом данных, объясняется тем, как эти два имеют дело с данными в памяти по-другому. Есть аналогичные концепции в C++, хотя имен в ABAP немного запутанным, когда вы привыкли к C++:

В ABAP символ поля немного как ссылки в C++ (или как разыменованного C++ указатель, как это делает SAP). Он не выделяет память для своих собственных данных, а скорее относится к некоторому существующему объекту field/data. После присвоения объекта данных символу поля, если вы обращаетесь к этому объекту данных через символ поля, вы никогда не разговариваете с самим символом поля, а всегда напрямую перед объектом данных! (Это важная часть в вашем случае, как мы видим в немного.)

Теперь в вашем первом примере создать символ поля, который ничего не делает еще:

FIELD-SYMBOLS: <lfs_struct> TYPE REF TO DATA. 

только после создания новой строки для вашей внутренней таблицы и назначения этой вновь выделенной памяти вашему полю символа <lfs_struct>, символ поля указывает на некоторые данные (строка таблицы). Затем выделить несколько больше памяти динамически:

CREATE DATA <lfs_struct> TYPE (<lfs_field>-segnam). 

Теперь ваши внутренние таблицы ei_lines точек на вновь добавленную строку таблицы (адрес памяти), как это делает ваш символ поля. Этот адрес памяти, в свою очередь, указывает на вновь созданные данные от CREATE DATA. Важно отметить, что, как сказано, вы не получаете доступ к самому символу поля, а к памяти, к которой он относится!

Во втором примереоднако сначала выделить память для нового объекта данных:

DATA: lo_struct TYPE REF TO data. 

Затем вы снова выделить новую память для новой строки таблицы (APPEND) и поместить ссылку на этот адрес памяти в ваш объект данных lo_struct.Теперь интересная часть: вы динамически создаете другие данные (объект) и сохраняете указатель на эти новые данные в lo_struct. Таким образом, теперь lo_struct больше не ссылается на новую строку таблицы, а на вновь созданные данные от CREATE DATA.


TL; DR В первом примере вы CREATE DATA и сохранить ссылку на эти данные в объект, где ваш символ поля <lfs_struct> относится, что новая строка таблицы в ei_lines. Во втором примере, однако, вы также создаете новую строку таблицы и ссылаетесь на нее через lo_struct, но после того, как вы выберете CREATE DATA, вы снова сохраните ссылку на эти новые данные в lo_struct, таким образом перезапирая исходную ссылку на новую строку таблицы.

+1

Спасибо, я думаю, что получил это сейчас! –

 Смежные вопросы

  • Нет связанных вопросов^_^