何时使用 FIELD-SYMBOLS
When to use FIELD-SYMBOLS
我不太明白何时使用 FIELD-SYMBOLS。它们就像 C/C++ 中的指针,但我们在该语言的任何地方都使用它们。只需:
使用有什么区别
DATA gt_mara LIKE TABLE OF mara.
DATA gs_mara LIKE LINE OF gt_mara.
LOOP AT gt_mara INTO gs_mara.
"code
ENDLOOP.
和
DATA gt_mara LIKE TABLE OF mara.
FIELD-SYMBOLS <gs_mara> like LINE OF gt_mara.
LOOP AT gt_mara ASSIGNING <gs_mara>.
"code
ENDLOOP.
您的问题归结为 Value vs. Reference Semantics,我将引用该文章的部分内容:
Reference semantics are A Good Thing. We can’t live without pointers. We just don’t want our software to be One Gigantic Rats Nest Of Pointers. In C++, you can pick and choose where you want reference semantics (pointers/references) and where you’d like value semantics (where objects physically contain other objects etc). In a large system, there should be a balance. However if you implement absolutely everything as a pointer, you’ll get enormous speed hits.
Objects near the problem skin are larger than higher level objects. The identity of these “problem space” abstractions is usually more important than their “value.” Thus reference semantics should be used for problem-space objects.
在 ABAP 中,您将“问题-space 对象”建模为结构或 classes,因此这些值通常会使用引用语义。要引用 class 个实例,必须使用 references,它也可用于引用结构。所以对于ABAP中的引用,一般会使用引用而不是更有限的字段符号。
现在有了引用,你通常会遇到内存管理的问题,
只要堆上的值被引用,它就不能被垃圾收集,并且只能访问堆栈上的引用,直到堆栈被弹出。因此,管理引用的内存和检查引用是否仍然有效总是有一些开销。 ABAP Documentation states:
From a technical perspective, the field symbols are implemented by references or pointers, which are comparable to references in data reference variables. A data reference variable is declared in the same way as every other data object and the memory area for the reference it contains is in the data area of the ABAP program. However, the pointer assigned to a field symbol is exclusively managed by the ABAP runtime environment and is located in a memory area, which cannot be accessed directly in an ABAP program.
此外,(局部)字段符号只能在过程中声明(而不是例如作为实例成员),因此字段符号的生命周期永远不会长于局部变量的生命周期。只要不从 table 中删除任何内容,对 table 行的引用也是如此。这些保证可能允许 ABAP 内核在这种情况下更有效地处理字段符号(例如 this discussion)。
因此,在性能至关重要的情况下,字段符号是有意义的,并且复制结构²比传递引用要昂贵得多(尽管您希望保留值语义)。最好的例子是在大 tables 上的循环。当写回 table 字段符号也比 MODIFY
更容易将值复制回 table.
TLDR:首选循环内的 FIELD-SYMBOLS!
²当传递其他大数据对象(例如内部 tables 或字符串时,通过引用传递而不是复制也总是有意义的。幸运的是,ABAP 已经在幕后为这些类型做了这件事,并在它们发生变化时进行复制(以保持值语义)。
对于LOOP ... INTO structure
,结构是table行的副本。在每次循环迭代开始时,table 行的内容被复制到结构中。您可以更改结构,但这些更改不会反映在 table 中。当你想改变table的内容时,你必须显式地使用UPDATE
指令。
LOOP AT itab INTO structure.
structure-betrh = structure-betrw * exchange_rate.
UPDATE itab FROM structure INDEX sy-tabix.
ENDLOOP.
对于 LOOP ... ASSIGNING <field_symbol>
(或 LOOP ... REFERENCE INTO reference
),字段符号 直接指向 table 行 。您可以更改它,这些更改将直接应用于 table。
LOOP AT itab ASSIGNING <field_symbol>.
<field_symbol>-betrh = <field_symbol>-betrw * exchange_rate.
ENDLOOP.
当您只阅读 table 时,这也会更快,因为不会将时间浪费在不必要的数据复制上。
我不太明白何时使用 FIELD-SYMBOLS。它们就像 C/C++ 中的指针,但我们在该语言的任何地方都使用它们。只需:
使用有什么区别
DATA gt_mara LIKE TABLE OF mara.
DATA gs_mara LIKE LINE OF gt_mara.
LOOP AT gt_mara INTO gs_mara.
"code
ENDLOOP.
和
DATA gt_mara LIKE TABLE OF mara.
FIELD-SYMBOLS <gs_mara> like LINE OF gt_mara.
LOOP AT gt_mara ASSIGNING <gs_mara>.
"code
ENDLOOP.
您的问题归结为 Value vs. Reference Semantics,我将引用该文章的部分内容:
Reference semantics are A Good Thing. We can’t live without pointers. We just don’t want our software to be One Gigantic Rats Nest Of Pointers. In C++, you can pick and choose where you want reference semantics (pointers/references) and where you’d like value semantics (where objects physically contain other objects etc). In a large system, there should be a balance. However if you implement absolutely everything as a pointer, you’ll get enormous speed hits. Objects near the problem skin are larger than higher level objects. The identity of these “problem space” abstractions is usually more important than their “value.” Thus reference semantics should be used for problem-space objects.
在 ABAP 中,您将“问题-space 对象”建模为结构或 classes,因此这些值通常会使用引用语义。要引用 class 个实例,必须使用 references,它也可用于引用结构。所以对于ABAP中的引用,一般会使用引用而不是更有限的字段符号。
现在有了引用,你通常会遇到内存管理的问题,
只要堆上的值被引用,它就不能被垃圾收集,并且只能访问堆栈上的引用,直到堆栈被弹出。因此,管理引用的内存和检查引用是否仍然有效总是有一些开销。 ABAP Documentation states:
From a technical perspective, the field symbols are implemented by references or pointers, which are comparable to references in data reference variables. A data reference variable is declared in the same way as every other data object and the memory area for the reference it contains is in the data area of the ABAP program. However, the pointer assigned to a field symbol is exclusively managed by the ABAP runtime environment and is located in a memory area, which cannot be accessed directly in an ABAP program.
此外,(局部)字段符号只能在过程中声明(而不是例如作为实例成员),因此字段符号的生命周期永远不会长于局部变量的生命周期。只要不从 table 中删除任何内容,对 table 行的引用也是如此。这些保证可能允许 ABAP 内核在这种情况下更有效地处理字段符号(例如 this discussion)。
因此,在性能至关重要的情况下,字段符号是有意义的,并且复制结构²比传递引用要昂贵得多(尽管您希望保留值语义)。最好的例子是在大 tables 上的循环。当写回 table 字段符号也比 MODIFY
更容易将值复制回 table.
TLDR:首选循环内的 FIELD-SYMBOLS!
²当传递其他大数据对象(例如内部 tables 或字符串时,通过引用传递而不是复制也总是有意义的。幸运的是,ABAP 已经在幕后为这些类型做了这件事,并在它们发生变化时进行复制(以保持值语义)。
对于LOOP ... INTO structure
,结构是table行的副本。在每次循环迭代开始时,table 行的内容被复制到结构中。您可以更改结构,但这些更改不会反映在 table 中。当你想改变table的内容时,你必须显式地使用UPDATE
指令。
LOOP AT itab INTO structure.
structure-betrh = structure-betrw * exchange_rate.
UPDATE itab FROM structure INDEX sy-tabix.
ENDLOOP.
对于 LOOP ... ASSIGNING <field_symbol>
(或 LOOP ... REFERENCE INTO reference
),字段符号 直接指向 table 行 。您可以更改它,这些更改将直接应用于 table。
LOOP AT itab ASSIGNING <field_symbol>.
<field_symbol>-betrh = <field_symbol>-betrw * exchange_rate.
ENDLOOP.
当您只阅读 table 时,这也会更快,因为不会将时间浪费在不必要的数据复制上。